diff options
Diffstat (limited to 'idlc')
97 files changed, 20270 insertions, 0 deletions
diff --git a/idlc/inc/idlc/astarray.hxx b/idlc/inc/idlc/astarray.hxx new file mode 100644 index 000000000000..22ceccfce4a3 --- /dev/null +++ b/idlc/inc/idlc/astarray.hxx @@ -0,0 +1,62 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _IDLC_ASTARRAY_HXX_ +#define _IDLC_ASTARRAY_HXX_ + +#include <idlc/asttype.hxx> +#include <idlc/astscope.hxx> + +class AstArray : public AstType +{ +public: + AstArray(const ::rtl::OString& name, AstType* pType, const ExprList& rDimExpr, AstScope* pScope); + AstArray(AstType* pType, const ExprList& rDimExpr, AstScope* pScope); + + virtual ~AstArray() {} + + AstType* getType() + { return m_pType; } + void setType(AstType* pType) + { + m_pType = pType; + setName(makeName()); + } + ExprList* getDimExpressions() + { return &m_dimExpressions; } + sal_uInt32 getDimension() + { return m_dimension; } + +private: + ::rtl::OString makeName(); + + AstType* m_pType; + sal_uInt32 m_dimension; + ExprList m_dimExpressions; +}; + +#endif // _IDLC_ASTARRAY_HXX_ + diff --git a/idlc/inc/idlc/astattribute.hxx b/idlc/inc/idlc/astattribute.hxx new file mode 100644 index 000000000000..fe87c3779d7f --- /dev/null +++ b/idlc/inc/idlc/astattribute.hxx @@ -0,0 +1,121 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _IDLC_ASTATTRIBUTE_HXX_ +#define _IDLC_ASTATTRIBUTE_HXX_ + +#include <idlc/astdeclaration.hxx> +#include "idlc/astscope.hxx" + +#include "registry/types.h" +#include "rtl/ustring.hxx" + +namespace typereg { class Writer; } + +class AstAttribute: public AstDeclaration, public AstScope { +public: + AstAttribute( + sal_uInt32 flags, AstType const * type, rtl::OString const & name, + AstScope * scope): + AstDeclaration(NT_attribute, name, scope), + AstScope(NT_attribute), m_flags(flags), m_pType(type) + {} + + AstAttribute(NodeType nodeType, sal_uInt32 flags, AstType const * pType, const ::rtl::OString& name, AstScope* pScope) + : AstDeclaration(nodeType, name, pScope), AstScope(nodeType) + , m_flags(flags) + , m_pType(pType) + {} + virtual ~AstAttribute() {} + + void setExceptions( + rtl::OUString const * getDoc, DeclList const * getExc, + rtl::OUString const * setDoc, DeclList const * setExc) + { + if (getDoc != 0) { + m_getDocumentation = *getDoc; + } + if (getExc != 0) { + m_getExceptions = *getExc; + } + if (setDoc != 0) { + m_setDocumentation = *setDoc; + } + if (setExc != 0) { + m_setExceptions = *setExc; + } + } + + DeclList::size_type getGetExceptionCount() const + { return m_getExceptions.size(); } + + DeclList::size_type getSetExceptionCount() const + { return m_setExceptions.size(); } + + AstType const * getType() const + { return m_pType; } + sal_Bool isReadonly() const + { return ((m_flags & AF_READONLY) == AF_READONLY); } + sal_Bool isOptional() const + { return ((m_flags & AF_OPTIONAL) == AF_OPTIONAL); } + sal_Bool isAttribute() const + { return ((m_flags & AF_ATTRIBUTE) == AF_ATTRIBUTE); } + sal_Bool isProperty() const + { return ((m_flags & AF_PROPERTY) == AF_PROPERTY); } + sal_Bool isBound() const + { return ((m_flags & AF_BOUND) == AF_BOUND); } + sal_Bool isMayBeVoid() const + { return ((m_flags & AF_MAYBEVOID) == AF_MAYBEVOID); } + sal_Bool isConstrained() const + { return ((m_flags & AF_CONSTRAINED) == AF_CONSTRAINED); } + sal_Bool isTransient() const + { return ((m_flags & AF_TRANSIENT) == AF_TRANSIENT); } + sal_Bool isMayBeAmbiguous() const + { return ((m_flags & AF_MAYBEAMBIGUOUS) == AF_MAYBEAMBIGUOUS); } + sal_Bool isMayBeDefault() const + { return ((m_flags & AF_MAYBEDEFAULT) == AF_MAYBEDEFAULT); } + sal_Bool isRemoveable() const + { return ((m_flags & AF_REMOVEABLE) == AF_REMOVEABLE); } + + sal_Bool dumpBlob( + typereg::Writer & rBlob, sal_uInt16 index, sal_uInt16 * methodIndex); + +private: + void dumpExceptions( + typereg::Writer & writer, rtl::OUString const & documentation, + DeclList const & exceptions, RTMethodMode flags, + sal_uInt16 * methodIndex); + + const sal_uInt32 m_flags; + AstType const * m_pType; + rtl::OUString m_getDocumentation; + DeclList m_getExceptions; + rtl::OUString m_setDocumentation; + DeclList m_setExceptions; +}; + +#endif // _IDLC_ASTATTRIBUTE_HXX_ + diff --git a/idlc/inc/idlc/astbasetype.hxx b/idlc/inc/idlc/astbasetype.hxx new file mode 100644 index 000000000000..93f8eb8ba3b1 --- /dev/null +++ b/idlc/inc/idlc/astbasetype.hxx @@ -0,0 +1,62 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _IDLC_ASTBASETYPE_HXX_ +#define _IDLC_ASTBASETYPE_HXX_ + +#include <idlc/asttype.hxx> +#include <idlc/astexpression.hxx> + + +class AstBaseType : public AstType +{ +public: + AstBaseType(const ExprType type, const ::rtl::OString& name, AstScope* pScope) + : AstType(NT_predefined, name, pScope) + , m_exprType(type) + {} + + virtual ~AstBaseType() {} + + virtual bool isUnsigned() const { + switch (m_exprType) { + case ET_ushort: + case ET_ulong: + case ET_uhyper: + return true; + default: + return false; + } + } + + ExprType getExprType() const + { return m_exprType; } +private: + const ExprType m_exprType; +}; + +#endif // _IDLC_ASTBASETYPE_HXX_ + diff --git a/idlc/inc/idlc/astconstant.hxx b/idlc/inc/idlc/astconstant.hxx new file mode 100644 index 000000000000..f116ef813825 --- /dev/null +++ b/idlc/inc/idlc/astconstant.hxx @@ -0,0 +1,57 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _IDLC_ASTCONSTANT_HXX_ +#define _IDLC_ASTCONSTANT_HXX_ + +#include <idlc/astdeclaration.hxx> +#include <idlc/astexpression.hxx> + +namespace typereg { class Writer; } + +class AstConstant : public AstDeclaration +{ +public: + AstConstant(const ExprType type, const NodeType nodeType, + AstExpression* pExpr, const ::rtl::OString& name, AstScope* pScope); + AstConstant(const ExprType type, AstExpression* pExpr, + const ::rtl::OString& name, AstScope* pScope); + virtual ~AstConstant(); + + AstExpression* getConstValue() + { return m_pConstValue; } + ExprType getConstValueType() const + { return m_constValueType; } + + sal_Bool dumpBlob( + typereg::Writer & rBlob, sal_uInt16 index, bool published); +private: + AstExpression* m_pConstValue; + const ExprType m_constValueType; +}; + +#endif // _IDLC_ASTCONSTANT_HXX_ + diff --git a/idlc/inc/idlc/astconstants.hxx b/idlc/inc/idlc/astconstants.hxx new file mode 100644 index 000000000000..283dbbefd981 --- /dev/null +++ b/idlc/inc/idlc/astconstants.hxx @@ -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. + * + ************************************************************************/ +#ifndef _IDLC_ASTCONSTANTS_HXX_ +#define _IDLC_ASTCONSTANTS_HXX_ + +#include <idlc/astmodule.hxx> + +class AstConstants : public AstModule +{ +public: + AstConstants(const ::rtl::OString& name, AstScope* pScope) + : AstModule(NT_constants, name, pScope) + {} + virtual ~AstConstants() {} +}; + +#endif // _IDLC_ASTCONSTANTS_HXX_ + diff --git a/idlc/inc/idlc/astdeclaration.hxx b/idlc/inc/idlc/astdeclaration.hxx new file mode 100644 index 000000000000..ecbe7e307f4f --- /dev/null +++ b/idlc/inc/idlc/astdeclaration.hxx @@ -0,0 +1,148 @@ +/************************************************************************* + * + * 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 _IDLC_ASTDECLARATION_HXX_ +#define _IDLC_ASTDECLARATION_HXX_ + +#include <idlc/idlc.hxx> +#include <registry/registry.hxx> + +class AstScope; + +// Enum defining the different kinds of Ast nodes +enum NodeType +{ + NT_object, // Denotes an object + NT_service, // Denotes an servcie + NT_interface_member, // Denotes an interface which is exported from object + NT_service_member, // Denotes an service which is exported from object + NT_observes, // Denotes an observed interface + NT_needs, // Denotes an needed service + NT_module, // Denotes a module + NT_root, // Denotes the root of AST + NT_interface, // Denotes an interface + NT_constants, // Denotes a constant group + NT_const, // Denotes a constant + NT_exception, // Denotes an exception + NT_attribute, // Denotes an attribute + NT_property, // Denotes an property + NT_operation, // Denotes an operation + NT_parameter, // Denotes an op. parameter + NT_union, // Denotes a union + NT_union_branch, // Denotes a union branch + NT_struct, // Denotes either a plain struct type, or a + // polymorphic struct type template + NT_type_parameter, // Denotes a type parameter of a polymorphic struct + // type template + NT_instantiated_struct, // Denotes an instantiated polymorphic struct type + NT_member, // Denotes a member in structure, exception + NT_enum, // Denotes an enumeration + NT_enum_val, // Denotes an enum. value + NT_array, // Denotes an IDL array + NT_sequence, // Denotes an IDL sequence + NT_typedef, // Denotes a typedef + NT_predefined, // Denotes a predefined type + NT_singleton // Denotes a singleton +}; + +class AstDeclaration +{ +public: + // Constructors + AstDeclaration(NodeType type, const ::rtl::OString& name, AstScope* pScope); + virtual ~AstDeclaration(); + + // Data access + void setName(const ::rtl::OString& name); + const ::rtl::OString& getLocalName() const + { return m_localName; } + const ::rtl::OString& getScopedName() const + { return m_scopedName; } + const ::rtl::OString& getFullName() + { return m_fullName; } + virtual const sal_Char* getRelativName() const + { return m_fullName.getStr()+1; } + AstScope* getScope() + { return m_pScope; } + void setScope(AstScope* pSc) + { m_pScope = pSc; } + NodeType getNodeType() const + { return m_nodeType; } + sal_Bool isInMainfile() const + { return m_bInMainFile; } + void setInMainfile(sal_Bool bInMainfile) + { m_bInMainFile = bInMainfile; } + sal_Bool isImported() const + { return m_bImported; } + void setImported(sal_Bool bImported) + { m_bImported = bImported; } + sal_Int32 getLineNumber() const + { return m_lineNumber; } + void setLineNumber(sal_Int32 lineNumber) + { m_lineNumber = lineNumber; } + const ::rtl::OString& getFileName() const + { return m_fileName; } + void setFileName(const ::rtl::OString& rFileName) + { m_fileName = rFileName; } + const ::rtl::OUString& getDocumentation() const + { return m_documentation; } + void setDocumentation(const ::rtl::OUString& rDocumentation) + { m_documentation = rDocumentation; } + sal_Bool isAdded() + { return m_bIsAdded; } + void markAsAdded() + { m_bIsAdded = sal_True; } + + virtual bool isType() const; + + sal_Bool hasAncestor(AstDeclaration* pDecl); + + void setPublished() { m_bPublished = true; } + bool isPublished() const { return m_bPublished; } + + virtual sal_Bool dump(RegistryKey& rKey); + + bool isPredefined() { return m_bPredefined; } + void setPredefined(bool bPredefined); + +protected: + ::rtl::OString m_localName; + ::rtl::OString m_scopedName; // full qualified name + ::rtl::OString m_fullName; // full qualified name with '/' as seperator + AstScope* m_pScope; + NodeType m_nodeType; + sal_Bool m_bImported; // imported ? + sal_Bool m_bIsAdded; // mark declaration as added in scope + sal_Bool m_bInMainFile; // defined in main file + bool m_bPublished; + bool m_bPredefined; + sal_Int32 m_lineNumber; // line number defined in + ::rtl::OString m_fileName; // fileName defined in + ::rtl::OUString m_documentation; // fileName defined in +}; + +#endif // _IDLC_ASTDECLARATION_HXX_ + diff --git a/idlc/inc/idlc/astenum.hxx b/idlc/inc/idlc/astenum.hxx new file mode 100644 index 000000000000..e125a907a68a --- /dev/null +++ b/idlc/inc/idlc/astenum.hxx @@ -0,0 +1,57 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _IDLC_ASTENUM_HXX_ +#define _IDLC_ASTENUM_HXX_ + +#include <idlc/asttype.hxx> +#include <idlc/astscope.hxx> +#include <idlc/astconstant.hxx> + +class AstEnum : public AstType + , public AstScope +{ +public: + AstEnum(const ::rtl::OString& name, AstScope* pScope); + + virtual ~AstEnum(); + + void setEnumValueCount(sal_Int32 count) + { m_enumValueCount = count; } + sal_Int32 getEnumValueCount() + { return m_enumValueCount++; } + + AstConstant* checkValue(AstExpression* pExpr); + + virtual sal_Bool dump(RegistryKey& rKey); + + virtual AstDeclaration* addDeclaration(AstDeclaration* pDecl); +private: + sal_Int32 m_enumValueCount; +}; + +#endif // _IDLC_ASTENUM_HXX_ + diff --git a/idlc/inc/idlc/astexception.hxx b/idlc/inc/idlc/astexception.hxx new file mode 100644 index 000000000000..915479461d8a --- /dev/null +++ b/idlc/inc/idlc/astexception.hxx @@ -0,0 +1,43 @@ +/************************************************************************* + * + * 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 _IDLC_ASTEXCEPTION_HXX_ +#define _IDLC_ASTEXCEPTION_HXX_ + +#include <idlc/aststruct.hxx> + +class AstException : public AstStruct +{ +public: + AstException(const ::rtl::OString& name, AstException* pBaseType, AstScope* pScope) + : AstStruct(NT_exception, name, pBaseType, pScope) + {} + + virtual ~AstException() {} +}; + +#endif // _IDLC_ASTEXCEPTION_HXX_ + diff --git a/idlc/inc/idlc/astexpression.hxx b/idlc/inc/idlc/astexpression.hxx new file mode 100644 index 000000000000..c5815ce5a252 --- /dev/null +++ b/idlc/inc/idlc/astexpression.hxx @@ -0,0 +1,186 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _IDLC_ASTEXPRESSION_HXX_ +#define _IDLC_ASTEXPRESSION_HXX_ + +#include <idlc/idlc.hxx> + +// Enum to define all the different operators to combine expressions +enum ExprComb +{ + EC_add, // '+' + EC_minus, // '-' + EC_mul, // '*' + EC_div, // '/' + EC_mod, // '%' + EC_or, // '|' + EC_xor, // '^' + EC_and, // '&' + EC_left, // '<<' + EC_right, // '>>' + EC_u_plus, // unary '+' + EC_u_minus, // unary '-' + EC_bit_neg, // '~' + EC_none, // No operator (missing) + EC_symbol // a symbol (function or constant name) +}; + +// Enum to define the different kinds of evaluation possible +enum EvalKind +{ + EK_const, // Must evaluate to constant + EK_positive_int // Must evaluate to positive integer +}; + +// Enum to define expression type +enum ExprType +{ + ET_short, // Expression value is short + ET_ushort, // Expression value is unsigned short + ET_long, // Expression value is long + ET_ulong, // Expression value is unsigned long + ET_hyper, // Expression value is hyper (64 bit) + ET_uhyper, // Expression value is unsigned hyper + ET_float, // Expression value is 32-bit float + ET_double, // Expression value is 64-bit float + ET_char, // Expression value is char + ET_byte, // Expression value is byte + ET_boolean, // Expression value is boolean + ET_string, // Expression value is char * + ET_any, // Expression value is any of above + ET_void, // Expression value is void (absent) + ET_type, // Expression value is type + ET_none // Expression value is missing +}; + +// Structure to describe value of constant expression and its type +struct AstExprValue +{ + union + { + sal_uInt8 byval; // Contains byte expression value + sal_Int16 sval; // Contains short expression value + sal_uInt16 usval; // Contains unsigned short expr value + sal_Int32 lval; // Contains long expression value + sal_uInt32 ulval; // Contains unsigned long expr value + sal_Int64 hval; // Contains hyper expression value + sal_uInt64 uhval; // Contains unsigned hyper expr value + sal_Bool bval; // Contains boolean expression value + float fval; // Contains 32-bit float expr value + double dval; // Contains 64-bit float expr value + sal_uInt32 eval; // Contains enumeration value + } u; + ExprType et; +}; + +const sal_Char* SAL_CALL exprTypeToString(ExprType t); + +class AstExpression +{ +public: + // Constructor(s) + AstExpression(ExprComb c, AstExpression *pExpr1, AstExpression *pExpr2); + + AstExpression(sal_Int32 l); + AstExpression(sal_Int32 l, ExprType et); + AstExpression(sal_Int64 h); + AstExpression(sal_uInt64 uh); + AstExpression(double d); + AstExpression(::rtl::OString* scopedName); + + virtual ~AstExpression(); + + // Data Accessors + AstScope* getScope() + { return m_pScope; } + void setScope(AstScope* pScope) + { m_pScope = pScope; } + sal_Int32 getLine() + { return m_lineNo; } + void setLine(sal_Int32 l) + { m_lineNo = l; } + const ::rtl::OString& getFileName() + { return m_fileName; } + void setFileName(const ::rtl::OString& fileName) + { m_fileName = fileName; } + ExprComb getCombOperator() + { return m_combOperator; } + void setCombOperator(ExprComb new_ec) + { m_combOperator = new_ec; } + AstExprValue* getExprValue() + { return m_exprValue; } + void setExprValue(AstExprValue *pEv) + { m_exprValue = pEv; } + AstExpression* getExpr1() + { return m_subExpr1; } + void setExpr1(AstExpression *pExpr) + { m_subExpr1 = pExpr; } + AstExpression* getExpr2() + { return m_subExpr2; } + void setExpr2(AstExpression *pExpr) + { m_subExpr2 = pExpr; } + ::rtl::OString* getSymbolicName() + { return m_pSymbolicName; } + void setSymbolicName(::rtl::OString* pSymbolicName) + { m_pSymbolicName = pSymbolicName; } + + // Evaluation and value coercion + AstExprValue* coerce(ExprType type, sal_Bool bAssign=sal_True); + + // Evaluate then store value inside this AstExpression + void evaluate(EvalKind ek); + + // Compare to AstExpressions + sal_Bool operator==(AstExpression *pExpr); + sal_Bool compare(AstExpression *pExpr); + + ::rtl::OString toString(); + void dump() {} +private: + // Fill out the lineno, filename and definition scope details + void fillDefinitionDetails(); + // Internal evaluation + AstExprValue* eval_internal(EvalKind ek); + // Evaluate different sets of operators + AstExprValue* eval_bin_op(EvalKind ek); + AstExprValue* eval_bit_op(EvalKind ek); + AstExprValue* eval_un_op(EvalKind ek); + AstExprValue* eval_symbol(EvalKind ek); + + AstScope* m_pScope; // scope defined in + sal_Int32 m_lineNo; // line number defined in + ::rtl::OString m_fileName; // fileName defined in + + ExprComb m_combOperator; + AstExpression* m_subExpr1; + AstExpression* m_subExpr2; + AstExprValue* m_exprValue; + ::rtl::OString* m_pSymbolicName; +}; + +#endif // _IDLC_ASTEXPRESSION_HXX_ + diff --git a/idlc/inc/idlc/astinterface.hxx b/idlc/inc/idlc/astinterface.hxx new file mode 100644 index 000000000000..f14fc640a2ee --- /dev/null +++ b/idlc/inc/idlc/astinterface.hxx @@ -0,0 +1,143 @@ +/************************************************************************* + * + * 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 _IDLC_ASTINTERFACE_HXX_ +#define _IDLC_ASTINTERFACE_HXX_ + +#include <idlc/asttype.hxx> +#include <idlc/astscope.hxx> +#include "idlc/inheritedinterface.hxx" + +#include <map> +#include <vector> + +class AstInterface : public AstType + , public AstScope +{ +public: + typedef std::vector< InheritedInterface > InheritedInterfaces; + + typedef std::vector< AstInterface const * > DoubleInterfaceDeclarations; + + struct DoubleMemberDeclaration { + AstDeclaration const * first; + AstDeclaration const * second; + }; + + typedef std::vector< DoubleMemberDeclaration > DoubleMemberDeclarations; + + struct DoubleDeclarations { + DoubleInterfaceDeclarations interfaces; + DoubleMemberDeclarations members; + }; + + AstInterface( + const ::rtl::OString& name, AstInterface const * pInherits, + AstScope* pScope); + virtual ~AstInterface(); + + InheritedInterfaces const & getAllInheritedInterfaces() const + { return m_inheritedInterfaces; } + + bool hasMandatoryInheritedInterfaces() const + { return m_mandatoryInterfaces > 0; } + + void setForwarded(sal_Bool bForwarded) + { m_bForwarded = bForwarded; } + sal_Bool isForwarded() + { return m_bForwarded; } + void setForwardedInSameFile(sal_Bool bForwarded) + { m_bForwardedInSameFile = bForwarded; } + sal_Bool isForwardedInSameFile() + { return m_bForwardedInSameFile; } + + void setDefined() { m_bIsDefined = true; } + sal_Bool isDefined() const + { return m_bIsDefined; } + + bool usesSingleInheritance() const { return m_bSingleInheritance; } + + DoubleDeclarations checkInheritedInterfaceClashes( + AstInterface const * ifc, bool optional) const; + + void addInheritedInterface( + AstType const * ifc, bool optional, + rtl::OUString const & documentation); + + DoubleMemberDeclarations checkMemberClashes( + AstDeclaration const * member) const; + + void addMember(AstDeclaration /*TODO: const*/ * member); + + void forwardDefined(AstInterface const & def); + + virtual sal_Bool dump(RegistryKey& rKey); + +private: + enum InterfaceKind { + INTERFACE_INDIRECT_OPTIONAL, INTERFACE_DIRECT_OPTIONAL, + INTERFACE_INDIRECT_MANDATORY, INTERFACE_DIRECT_MANDATORY }; + + struct VisibleMember { + explicit VisibleMember(AstDeclaration const * theMandatory = 0): + mandatory(theMandatory) {} + + typedef std::map< rtl::OString, AstDeclaration const * > Optionals; + + AstDeclaration const * mandatory; + Optionals optionals; + }; + + typedef std::map< rtl::OString, InterfaceKind > VisibleInterfaces; + typedef std::map< rtl::OString, VisibleMember > VisibleMembers; + + void checkInheritedInterfaceClashes( + DoubleDeclarations & doubleDeclarations, + std::set< rtl::OString > & seenInterfaces, AstInterface const * ifc, + bool optional, bool direct, bool mainOptional) const; + + void checkMemberClashes( + DoubleMemberDeclarations & doubleMembers, AstDeclaration const * member, + bool checkOptional) const; + + void addVisibleInterface( + AstInterface const * ifc, bool direct, bool optional); + + void addOptionalVisibleMembers(AstInterface const * ifc); + + bool increment(sal_uInt16 * counter, char const * sort) const; + + InheritedInterfaces m_inheritedInterfaces; + InheritedInterfaces::size_type m_mandatoryInterfaces; + sal_Bool m_bIsDefined; + sal_Bool m_bForwarded; + sal_Bool m_bForwardedInSameFile; + bool m_bSingleInheritance; + VisibleInterfaces m_visibleInterfaces; + VisibleMembers m_visibleMembers; +}; + +#endif // _IDLC_ASTINTERFACE_HXX_ diff --git a/idlc/inc/idlc/astinterfacemember.hxx b/idlc/inc/idlc/astinterfacemember.hxx new file mode 100644 index 000000000000..65c6eb309299 --- /dev/null +++ b/idlc/inc/idlc/astinterfacemember.hxx @@ -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. + * + ************************************************************************/ +#ifndef _IDLC_ASTINTERFACEMEMBER_HXX_ +#define _IDLC_ASTINTERFACEMEMBER_HXX_ + +#include <idlc/astinterface.hxx> + +class AstInterfaceMember : public AstDeclaration +{ +public: + AstInterfaceMember(const sal_uInt32 flags, AstInterface* pRealInterface, + const ::rtl::OString& name, AstScope* pScope) + : AstDeclaration(NT_interface_member, name, pScope) + , m_flags(flags) + , m_pRealInterface(pRealInterface) + {} + virtual ~AstInterfaceMember() {} + + AstInterface* getRealInterface() + { return m_pRealInterface; } + sal_Bool isOptional() + { return ((m_flags & AF_OPTIONAL) == AF_OPTIONAL); } +private: + const sal_uInt32 m_flags; + AstInterface* m_pRealInterface; +}; + +#endif // _IDLC_ASTINTERFACEMEMBER_HXX_ + diff --git a/idlc/inc/idlc/astmember.hxx b/idlc/inc/idlc/astmember.hxx new file mode 100644 index 000000000000..27a0b900fd7c --- /dev/null +++ b/idlc/inc/idlc/astmember.hxx @@ -0,0 +1,57 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _IDLC_ASTMEMBER_HXX_ +#define _IDLC_ASTMEMBER_HXX_ + +#include "idlc/astdeclaration.hxx" + +namespace rtl { class OString; } +class AstScope; +class AstType; + +class AstMember: public AstDeclaration { +public: + AstMember( + AstType const * pType, rtl::OString const & name, AstScope * pScope): + AstDeclaration(NT_member, name, pScope), m_pType(pType) {} + + virtual ~AstMember() {} + + AstType const * getType() const { return m_pType; } + +protected: + AstMember( + NodeType type, AstType const * pType, rtl::OString const & name, + AstScope * pScope): + AstDeclaration(type, name, pScope), m_pType(pType) {} + +private: + AstType const * m_pType; +}; + +#endif diff --git a/idlc/inc/idlc/astmodule.hxx b/idlc/inc/idlc/astmodule.hxx new file mode 100644 index 000000000000..e9b18971f2a9 --- /dev/null +++ b/idlc/inc/idlc/astmodule.hxx @@ -0,0 +1,51 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _IDLC_ASTMODULE_HXX_ +#define _IDLC_ASTMODULE_HXX_ + +#include <idlc/astdeclaration.hxx> +#include <idlc/astscope.hxx> + +class AstModule : public AstDeclaration + , public AstScope +{ +public: + AstModule(const ::rtl::OString& name, AstScope* pScope) + : AstDeclaration(NT_module, name, pScope) + , AstScope(NT_module) + {} + AstModule(NodeType type, const ::rtl::OString& name, AstScope* pScope) + : AstDeclaration(type, name, pScope) + , AstScope(type) + {} + virtual ~AstModule() {} + + virtual sal_Bool dump(RegistryKey& rKey); +}; + +#endif // _IDLC_ASTMODULE_HXX_ + diff --git a/idlc/inc/idlc/astneeds.hxx b/idlc/inc/idlc/astneeds.hxx new file mode 100644 index 000000000000..3e5194f7ae0a --- /dev/null +++ b/idlc/inc/idlc/astneeds.hxx @@ -0,0 +1,48 @@ +/************************************************************************* + * + * 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 _IDLC_ASTNEEDS_HXX_ +#define _IDLC_ASTNEEDS_HXX_ + +#include <idlc/astservice.hxx> + +class AstNeeds : public AstDeclaration +{ +public: + AstNeeds(AstService* pRealService, const ::rtl::OString& name, AstScope* pScope) + : AstDeclaration(NT_needs, name, pScope) + , m_pRealService(pRealService) + {} + virtual ~AstNeeds() {} + + AstService* getRealService() + { return m_pRealService; } +private: + AstService* m_pRealService; +}; + +#endif // _IDLC_ASTNEEDS_HXX_ + diff --git a/idlc/inc/idlc/astobserves.hxx b/idlc/inc/idlc/astobserves.hxx new file mode 100644 index 000000000000..58ca38b9d25a --- /dev/null +++ b/idlc/inc/idlc/astobserves.hxx @@ -0,0 +1,48 @@ +/************************************************************************* + * + * 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 _IDLC_ASTOBSERVES_HXX_ +#define _IDLC_ASTOBSERVES_HXX_ + +#include <idlc/astinterface.hxx> + +class AstObserves : public AstDeclaration +{ +public: + AstObserves(AstInterface* pRealInterface, const ::rtl::OString& name, AstScope* pScope) + : AstDeclaration(NT_observes, name, pScope) + , m_pRealInterface(pRealInterface) + {} + virtual ~AstObserves() {} + + AstInterface* getRealInterface() + { return m_pRealInterface; } +private: + AstInterface* m_pRealInterface; +}; + +#endif // _IDLC_ASTOBSERVES_HXX_ + diff --git a/idlc/inc/idlc/astoperation.hxx b/idlc/inc/idlc/astoperation.hxx new file mode 100644 index 000000000000..456d25e91c92 --- /dev/null +++ b/idlc/inc/idlc/astoperation.hxx @@ -0,0 +1,76 @@ +/************************************************************************* + * + * 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 _IDLC_ASTOPERATION_HXX_ +#define _IDLC_ASTOPERATION_HXX_ + +#include <idlc/astdeclaration.hxx> +#include <idlc/astscope.hxx> + +namespace typereg { class Writer; } + +#define OP_NONE 0x0000 +#define OP_ONEWAY 0x0001 + +class AstType; + +class AstOperation : public AstDeclaration + , public AstScope +{ +public: + AstOperation(sal_uInt32 flags, AstType* pReturnType, const ::rtl::OString& name, AstScope* pScope) + : AstDeclaration(NT_operation, name, pScope) + , AstScope(NT_operation) + , m_flags(flags) + , m_pReturnType(pReturnType) + {} + virtual ~AstOperation() {} + + sal_Bool isOneway() + { return ((m_flags & OP_ONEWAY) == OP_ONEWAY); } + + bool isVariadic() const; + + bool isConstructor() const { return m_pReturnType == 0; } + + void setExceptions(DeclList const * pExceptions); + const DeclList& getExceptions() + { return m_exceptions; } + sal_uInt16 nExceptions() + { return (sal_uInt16)(m_exceptions.size()); } + + sal_Bool dumpBlob(typereg::Writer & rBlob, sal_uInt16 index); + + // scope management + virtual AstDeclaration* addDeclaration(AstDeclaration* pDecl); +private: + sal_uInt32 m_flags; + AstType* m_pReturnType; + DeclList m_exceptions; +}; + +#endif // _IDLC_ASTOPERATION_HXX_ + diff --git a/idlc/inc/idlc/astparameter.hxx b/idlc/inc/idlc/astparameter.hxx new file mode 100644 index 000000000000..c2178a613d9f --- /dev/null +++ b/idlc/inc/idlc/astparameter.hxx @@ -0,0 +1,54 @@ +/************************************************************************* + * + * 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 _IDLC_ASTPARAMETER_HXX_ +#define _IDLC_ASTPARAMETER_HXX_ + +#include <idlc/astmember.hxx> + +enum Direction { DIR_IN, DIR_OUT, DIR_INOUT }; + +class AstParameter: public AstMember { +public: + AstParameter( + Direction direction, bool rest, AstType const * type, + rtl::OString const & name, AstScope * scope): + AstMember(NT_parameter, type, name, scope), m_direction(direction), + m_rest(rest) {} + + virtual ~AstParameter() {} + + Direction getDirection() const { return m_direction; } + + bool isRest() const { return m_rest; } + +private: + Direction m_direction; + bool m_rest; +}; + +#endif diff --git a/idlc/inc/idlc/astscope.hxx b/idlc/inc/idlc/astscope.hxx new file mode 100644 index 000000000000..97b44787b80c --- /dev/null +++ b/idlc/inc/idlc/astscope.hxx @@ -0,0 +1,78 @@ +/************************************************************************* + * + * 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 _IDLC_ASTSCOPE_HXX_ +#define _IDLC_ASTSCOPE_HXX_ + +#include <idlc/idlc.hxx> + +class AstExpression; +#include <idlc/astdeclaration.hxx> +#include <idlc/astexpression.hxx> + +class AstScope +{ +public: + AstScope(NodeType nodeType); + virtual ~AstScope(); + + NodeType getScopeNodeType() const + { return m_nodeType; } + + virtual AstDeclaration* addDeclaration(AstDeclaration* pDecl); + + sal_uInt32 nMembers() const + { return (sal_uInt32)(m_declarations.size()); } + DeclList::const_iterator getIteratorBegin() const + { return m_declarations.begin(); } + DeclList::const_iterator getIteratorEnd() const + { return m_declarations.end(); } + sal_uInt16 getNodeCount(NodeType nType); + + // Name look up mechanism + AstDeclaration* lookupByName(const ::rtl::OString& scopedName); + // Look up the identifier 'name' specified only in the local scope + AstDeclaration* lookupByNameLocal(const ::rtl::OString& name) const; + + AstDeclaration* lookupInForwarded(const ::rtl::OString& scopedName); + AstDeclaration* lookupInInherited(const ::rtl::OString& scopedName) const; + + // Look up a predefined type by its ExprType + AstDeclaration* lookupPrimitiveType(ExprType type); + + AstDeclaration* lookupForAdd(AstDeclaration* pDecl); + +protected: + inline AstDeclaration const * getLast() const + { return m_declarations.back(); } + +private: + DeclList m_declarations; + NodeType m_nodeType; +}; + +#endif // _IDLC_ASTSCOPE_HXX_ + diff --git a/idlc/inc/idlc/astsequence.hxx b/idlc/inc/idlc/astsequence.hxx new file mode 100644 index 000000000000..120528f1d419 --- /dev/null +++ b/idlc/inc/idlc/astsequence.hxx @@ -0,0 +1,59 @@ +/************************************************************************* + * + * 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 _IDLC_ASTSEQUENCE_HXX_ +#define _IDLC_ASTSEQUENCE_HXX_ + +#include <idlc/asttype.hxx> + +class AstSequence : public AstType +{ +public: + AstSequence(AstType* pMemberType, AstScope* pScope) + : AstType(NT_sequence, ::rtl::OString("[]")+pMemberType->getScopedName(), pScope) + , m_pMemberType(pMemberType) + , m_pRelativName(NULL) + {} + virtual ~AstSequence() + { + if ( m_pRelativName ) + delete m_pRelativName; + } + + AstType* getMemberType() const + { return m_pMemberType; } + + virtual bool isUnsigned() const + { return m_pMemberType != 0 && m_pMemberType->isUnsigned(); } + + virtual const sal_Char* getRelativName() const; +private: + AstType* m_pMemberType; + mutable ::rtl::OString* m_pRelativName; +}; + +#endif // _IDLC_ASTSEQUENCE_HXX_ + diff --git a/idlc/inc/idlc/astservice.hxx b/idlc/inc/idlc/astservice.hxx new file mode 100644 index 000000000000..f327a0dfbba8 --- /dev/null +++ b/idlc/inc/idlc/astservice.hxx @@ -0,0 +1,60 @@ +/************************************************************************* + * + * 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 _IDLC_ASTSERVICE_HXX_ +#define _IDLC_ASTSERVICE_HXX_ + +#include <idlc/astdeclaration.hxx> +#include <idlc/astscope.hxx> + +class AstService : public AstDeclaration + , public AstScope +{ +public: + AstService(const ::rtl::OString& name, AstScope* pScope) + : AstDeclaration(NT_service, name, pScope) + , AstScope(NT_service) + , m_defaultConstructor(false) + {} + AstService(const NodeType type, const ::rtl::OString& name, AstScope* pScope) + : AstDeclaration(type, name, pScope) + , AstScope(type) + , m_defaultConstructor(false) + {} + virtual ~AstService() {} + + virtual sal_Bool dump(RegistryKey& rKey); + + void setDefaultConstructor(bool b) { m_defaultConstructor = b; } + + bool checkLastConstructor() const; + +private: + bool m_defaultConstructor; +}; + +#endif // _IDLC_ASTSERVICE_HXX_ + diff --git a/idlc/inc/idlc/astservicemember.hxx b/idlc/inc/idlc/astservicemember.hxx new file mode 100644 index 000000000000..5a45fe2555ff --- /dev/null +++ b/idlc/inc/idlc/astservicemember.hxx @@ -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. + * + ************************************************************************/ +#ifndef _IDLC_ASTSERVICEMEMBER_HXX_ +#define _IDLC_ASTSERVICEMEMBER_HXX_ + +#include <idlc/astservice.hxx> + +class AstServiceMember : public AstDeclaration +{ +public: + AstServiceMember(const sal_uInt32 flags, AstService* pRealService, + const ::rtl::OString& name, AstScope* pScope) + : AstDeclaration(NT_service_member, name, pScope) + , m_flags(flags) + , m_pRealService(pRealService) + {} + virtual ~AstServiceMember() {} + + AstService* getRealService() + { return m_pRealService; } + sal_Bool isOptional() + { return ((m_flags & AF_OPTIONAL) == AF_OPTIONAL); } +private: + const sal_uInt32 m_flags; + AstService* m_pRealService; +}; + +#endif // _IDLC_ASTSERVICEMEMBER_HXX_ + diff --git a/idlc/inc/idlc/aststack.hxx b/idlc/inc/idlc/aststack.hxx new file mode 100644 index 000000000000..8d4c3dba58b1 --- /dev/null +++ b/idlc/inc/idlc/aststack.hxx @@ -0,0 +1,56 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _IDLC_ASTSTACK_HXX_ +#define _IDLC_ASTSTACK_HXX_ + +#include <sal/types.h> + +class AstScope; + +class AstStack +{ +public: + AstStack(); + virtual ~AstStack(); + + sal_uInt32 depth(); + AstScope* top(); + AstScope* bottom(); + AstScope* nextToTop(); + AstScope* topNonNull(); + AstStack* push(AstScope* pScope); + void pop(); + void clear(); + +private: + AstScope** m_stack; + sal_uInt32 m_size; + sal_uInt32 m_top; +}; + +#endif // _IDLC_ASTSTACK_HXX_ + diff --git a/idlc/inc/idlc/aststruct.hxx b/idlc/inc/idlc/aststruct.hxx new file mode 100644 index 000000000000..062865199a29 --- /dev/null +++ b/idlc/inc/idlc/aststruct.hxx @@ -0,0 +1,69 @@ +/************************************************************************* + * + * 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 _IDLC_ASTSTRUCT_HXX_ +#define _IDLC_ASTSTRUCT_HXX_ + +#include <idlc/asttype.hxx> +#include <idlc/astscope.hxx> +#include "idlc/idlctypes.hxx" + +class AstStruct; +typedef ::std::vector< AstStruct* > InheritedTypes; + +class AstStruct : public AstType + , public AstScope +{ +public: + AstStruct( + const ::rtl::OString& name, + std::vector< rtl::OString > const & typeParameters, + AstStruct* pBaseType, AstScope* pScope); + + AstStruct(const NodeType type, + const ::rtl::OString& name, + AstStruct* pBaseType, + AstScope* pScope); + virtual ~AstStruct(); + + AstStruct* getBaseType() + { return m_pBaseType; } + + DeclList::size_type getTypeParameterCount() const + { return m_typeParameters.size(); } + + AstDeclaration const * findTypeParameter(rtl::OString const & name) const; + + virtual bool isType() const; + + virtual sal_Bool dump(RegistryKey& rKey); +private: + AstStruct* m_pBaseType; + DeclList m_typeParameters; +}; + +#endif // _IDLC_ASTSTRUCT_HXX_ + diff --git a/idlc/inc/idlc/aststructinstance.hxx b/idlc/inc/idlc/aststructinstance.hxx new file mode 100644 index 000000000000..32b64c10026b --- /dev/null +++ b/idlc/inc/idlc/aststructinstance.hxx @@ -0,0 +1,56 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef INCLUDED_idlc_inc_idlc_aststructinstance_hxx +#define INCLUDED_idlc_inc_idlc_aststructinstance_hxx + +#include "idlc/asttype.hxx" +#include "idlc/idlctypes.hxx" + +class AstDeclaration; +class AstScope; + +class AstStructInstance: public AstType { +public: + AstStructInstance( + AstType const * typeTemplate, DeclList const * typeArguments, + AstScope * scope); + + AstType const * getTypeTemplate() const { return m_typeTemplate; } + + DeclList::const_iterator getTypeArgumentsBegin() const + { return m_typeArguments.begin(); } + + DeclList::const_iterator getTypeArgumentsEnd() const + { return m_typeArguments.end(); } + +private: + AstType const * m_typeTemplate; + DeclList m_typeArguments; +}; + +#endif diff --git a/idlc/inc/idlc/asttype.hxx b/idlc/inc/idlc/asttype.hxx new file mode 100644 index 000000000000..2e0274436c04 --- /dev/null +++ b/idlc/inc/idlc/asttype.hxx @@ -0,0 +1,45 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _IDLC_ASTTYPE_HXX_ +#define _IDLC_ASTTYPE_HXX_ + +#include <idlc/astdeclaration.hxx> + +class AstType : public AstDeclaration +{ +public: + AstType(const NodeType type, const ::rtl::OString& name, AstScope* pScope) + : AstDeclaration(type, name, pScope) + {} + + virtual ~AstType() {} + + virtual bool isUnsigned() const { return false; } +}; + +#endif // _IDLC_ASTTYPE_HXX_ + diff --git a/idlc/inc/idlc/asttypedef.hxx b/idlc/inc/idlc/asttypedef.hxx new file mode 100644 index 000000000000..e8f9ddedbfbe --- /dev/null +++ b/idlc/inc/idlc/asttypedef.hxx @@ -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. + * + ************************************************************************/ +#ifndef _IDLC_ASTTYPEDEF_HXX_ +#define _IDLC_ASTTYPEDEF_HXX_ + +#include <idlc/asttype.hxx> + +class AstTypeDef : public AstType +{ +public: + AstTypeDef( + AstType const * baseType, rtl::OString const & name, AstScope * scope): + AstType(NT_typedef, name, scope), m_pBaseType(baseType) {} + + virtual ~AstTypeDef() {} + + AstType const * getBaseType() const + { return m_pBaseType; } + + virtual bool isUnsigned() const + { return m_pBaseType != 0 && m_pBaseType->isUnsigned(); } + + virtual sal_Bool dump(RegistryKey& rKey); +private: + AstType const * m_pBaseType; +}; + +#endif // _IDLC_ASTTYPEDEF_HXX_ + diff --git a/idlc/inc/idlc/astunion.hxx b/idlc/inc/idlc/astunion.hxx new file mode 100644 index 000000000000..4976f02b117f --- /dev/null +++ b/idlc/inc/idlc/astunion.hxx @@ -0,0 +1,68 @@ +/************************************************************************* + * + * 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 _IDLC_ASTUNION_HXX_ +#define _IDLC_ASTUNION_HXX_ + +#include <idlc/aststruct.hxx> +#include <idlc/astunionbranch.hxx> + +class AstUnion : public AstStruct +{ +public: + AstUnion(const ::rtl::OString& name, AstType* pDiscType, AstScope* pScope); + virtual ~AstUnion(); + + AstType* getDiscrimantType() + { return m_pDiscriminantType; } + ExprType getDiscrimantExprType() + { return m_discExprType; } + + virtual sal_Bool dump(RegistryKey& rKey); + + virtual AstDeclaration* addDeclaration(AstDeclaration* pDecl); +protected: + // Look up a branch by node pointer + AstUnionBranch* lookupBranch(AstUnionBranch* pBranch); + + // Look up the branch with the "default" label + AstUnionBranch* lookupDefault(sal_Bool bReportError = sal_True ); + + // Look up a branch given a branch with a label. This is used to + // check for duplicate labels + AstUnionBranch* lookupLabel(AstUnionBranch* pBranch); + + // Look up a union branch given an enumerator. This is used to + // check for duplicate enum labels + AstUnionBranch* lookupEnum(AstUnionBranch* pBranch); + +private: + AstType* m_pDiscriminantType; + ExprType m_discExprType; +}; + +#endif // _IDLC_ASTUNION_HXX_ + diff --git a/idlc/inc/idlc/astunionbranch.hxx b/idlc/inc/idlc/astunionbranch.hxx new file mode 100644 index 000000000000..b1811983bd2f --- /dev/null +++ b/idlc/inc/idlc/astunionbranch.hxx @@ -0,0 +1,46 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _IDLC_ASTUNIONBRANCH_HXX_ +#define _IDLC_ASTUNIONBRANCH_HXX_ + +#include <idlc/astmember.hxx> +#include <idlc/astunionlabel.hxx> + +class AstUnionBranch : public AstMember +{ +public: + AstUnionBranch(AstUnionLabel* pLabel, AstType const * pType, const ::rtl::OString& name, AstScope* pScope); + virtual ~AstUnionBranch(); + + AstUnionLabel* getLabel() + { return m_pLabel; } +private: + AstUnionLabel* m_pLabel; +}; + +#endif // _IDLC_ASTUNIONBRANCH_HXX_ + diff --git a/idlc/inc/idlc/astunionlabel.hxx b/idlc/inc/idlc/astunionlabel.hxx new file mode 100644 index 000000000000..90bc263b7fd6 --- /dev/null +++ b/idlc/inc/idlc/astunionlabel.hxx @@ -0,0 +1,52 @@ +/************************************************************************* + * + * 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 _IDLC_ASTUNIONLABEL_HXX_ +#define _IDLC_ASTUNIONLABEL_HXX_ + +enum UnionLabel +{ + UL_default, // Label is "default" + UL_label // Regular label +}; + +class AstUnionLabel +{ +public: + AstUnionLabel(UnionLabel labelKind, AstExpression* pExpr); + virtual ~AstUnionLabel(); + + UnionLabel getLabelKind() + { return m_label; } + AstExpression* getLabelValue() + { return m_pLabelValue; } +private: + UnionLabel m_label; + AstExpression* m_pLabelValue; +}; + +#endif // _IDLC_ASTUNIONLABEL_HXX_ + diff --git a/idlc/inc/idlc/errorhandler.hxx b/idlc/inc/idlc/errorhandler.hxx new file mode 100644 index 000000000000..f651172459ae --- /dev/null +++ b/idlc/inc/idlc/errorhandler.hxx @@ -0,0 +1,157 @@ +/************************************************************************* + * + * 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 _IDLC_ERRORHANDLER_HXX_ +#define _IDLC_ERRORHANDLER_HXX_ + +#include <idlc/astdeclaration.hxx> +#include <idlc/astexpression.hxx> +#include <idlc/astunion.hxx> +#include <idlc/astenum.hxx> + +enum ErrorCode +{ + EIDL_NONE, // No error + EIDL_SYNTAX_ERROR, // Syntax error in IDL input + // More details will be gleaned from examining + // the parse state + EIDL_REDEF, // Redefinition + EIDL_REDEF_SCOPE, // Redefinition inside defining scope + EIDL_DEF_USE, // Definition after use + EIDL_MULTIPLE_BRANCH, // More than one union branch with this label + EIDL_COERCION_FAILURE, // Coercion failure + EIDL_SCOPE_CONFLICT, // Between fwd declare and full declare + EIDL_ONEWAY_CONFLICT, // Between op decl and argument direction + EIDL_DISC_TYPE, // Illegal discriminator type in union + EIDL_LABEL_TYPE, // Mismatch with discriminator type in union + EIDL_ILLEGAL_ADD, // Illegal add action + EIDL_ILLEGAL_USE, // Illegal type used in expression + EIDL_ILLEGAL_RAISES, // Error in "raises" clause + EIDL_CANT_INHERIT, // Cannot inherit from non-interface + EIDL_LOOKUP_ERROR, // Identifier not found + EIDL_INHERIT_FWD_ERROR, // Cannot inherit from fwd decl interface + EIDL_CONSTANT_EXPECTED, // We got something else.. + EIDL_NAME_CASE_ERROR, // Spelling differences found + EIDL_ENUM_VAL_EXPECTED, // Expected an enumerator + EIDL_ENUM_VAL_NOT_FOUND, // Didnt find an enumerator with that name + EIDL_EVAL_ERROR, // Error in evaluating expression + EIDL_AMBIGUOUS, // Ambiguous name definition + EIDL_DECL_NOT_DEFINED, // Forward declared but never defined + EIDL_FWD_DECL_LOOKUP, // Tried to lookup in fwd declared intf + EIDL_RECURSIVE_TYPE, // Illegal recursive use of type + EIDL_NONVOID_ONEWAY, // Non-void return type in oneway operation + EIDL_NOT_A_TYPE, // Not a type + EIDL_TYPE_NOT_VALID, // Type is not valid in this context + EIDL_INTERFACEMEMBER_LOOKUP, // interface is not defined or a fwd declaration not exists + EIDL_SERVICEMEMBER_LOOKUP, + EIDL_TYPE_IDENT_CONFLICT, // type and identifier has equal names + EIDL_ONEWAY_RAISE_CONFLICT, // oneway function raised excpetion conflict + EIDL_WRONGATTRIBUTEFLAG, + EIDL_DEFINED_ATTRIBUTEFLAG, + EIDL_WRONGATTRIBUTEKEYWORD, + EIDL_MISSINGATTRIBUTEKEYWORD, + EIDL_BAD_ATTRIBUTE_FLAGS, + EIDL_OPTIONALEXPECTED, + EIDL_MIXED_INHERITANCE, + EIDL_DOUBLE_INHERITANCE, + EIDL_DOUBLE_MEMBER, + EIDL_CONSTRUCTOR_PARAMETER_NOT_IN, + EIDL_CONSTRUCTOR_REST_PARAMETER_NOT_FIRST, + EIDL_REST_PARAMETER_NOT_LAST, + EIDL_REST_PARAMETER_NOT_ANY, + EIDL_METHOD_HAS_REST_PARAMETER, + EIDL_READONLY_ATTRIBUTE_SET_EXCEPTIONS, + EIDL_UNSIGNED_TYPE_ARGUMENT, + EIDL_WRONG_NUMBER_OF_TYPE_ARGUMENTS, + EIDL_INSTANTIATED_STRUCT_TYPE_TYPEDEF, + EIDL_IDENTICAL_TYPE_PARAMETERS, + EIDL_STRUCT_TYPE_TEMPLATE_WITH_BASE, + EIDL_PUBLISHED_FORWARD, + EIDL_PUBLISHED_USES_UNPUBLISHED, + EIDL_SIMILAR_CONSTRUCTORS +}; + +enum WarningCode +{ + WIDL_EXPID_CONFLICT, // exception id conflict + WIDL_REQID_CONFLICT, // request id conflict + WIDL_INHERIT_IDCONFLICT, // request id conflict inheritance tree + WIDL_TYPE_IDENT_CONFLICT, // type and identifier has equal names + WIDL_WRONG_NAMING_CONV // type or identifier doesn't fulfill the UNO naming convention +}; + +class ErrorHandler +{ +public: + // Report errors with varying numbers of arguments + void error0(ErrorCode e); + void error1(ErrorCode e, AstDeclaration const * d); + void error2( + ErrorCode e, AstDeclaration const * d1, AstDeclaration const * d2); + void error3(ErrorCode e, AstDeclaration* d1, AstDeclaration* d2, AstDeclaration* d3); + + // Warning + void warning0(WarningCode e, const sal_Char* warningmsg); + + // Report a syntax error in IDL input + void syntaxError(ParseState state, sal_Int32 lineNumber, const sal_Char* errmsg); + + // Report an unsuccesful coercion attempt + void coercionError(AstExpression *pExpr, ExprType et); + + // Report a failed name lookup attempt + void lookupError(const ::rtl::OString& n); + // Report a failed name lookup attempt + void lookupError(ErrorCode e, const ::rtl::OString& n, AstDeclaration* pScope); + + + // Report a type error + void noTypeError(AstDeclaration const * pDecl); + + void inheritanceError(NodeType nodeType, const ::rtl::OString* name, AstDeclaration* pDecl); + + void flagError(ErrorCode e, sal_uInt32 flag); + + void forwardLookupError(AstDeclaration* pForward, const ::rtl::OString& name); + + void constantExpected(AstDeclaration* pDecl, const ::rtl::OString& name); + + void evalError(AstExpression* pExpr); + + // Report a situation where an enumerator was expected but we got + // something else instead. This occurs when a union with an enum + // discriminator is being parsed and one of the branch labels is + // not an enumerator in that enum + void enumValExpected(AstUnion* pUnion); + + // Report a failed enumerator lookup in an enum + void enumValLookupFailure(AstUnion* pUnion, AstEnum* pEnum, const ::rtl::OString& name); + + bool checkPublished(AstDeclaration const * decl, bool bOptiional=false); +}; + +#endif // _IDLC_ERRORHANDLER_HXX_ + diff --git a/idlc/inc/idlc/fehelper.hxx b/idlc/inc/idlc/fehelper.hxx new file mode 100644 index 000000000000..2cd20e6bce0e --- /dev/null +++ b/idlc/inc/idlc/fehelper.hxx @@ -0,0 +1,98 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _IDLC_FEHELPER_HXX_ +#define _IDLC_FEHELPER_HXX_ + +#include <idlc/asttype.hxx> +#include <idlc/astinterface.hxx> + +#include <vector> + +class FeDeclarator +{ +public: + // Enum to denote types of declarators + enum DeclaratorType + { + FD_simple, // Simple declarator + FD_complex // Complex declarator (complex_part field used) + }; + + FeDeclarator(const ::rtl::OString& name, DeclaratorType declType, AstDeclaration* pComplPart); + virtual ~FeDeclarator(); + + AstDeclaration* getComplexPart() + { return m_pComplexPart; } + const ::rtl::OString& getName() + { return m_name; } + DeclaratorType getDeclType() + { return m_declType; } + + sal_Bool checkType(AstDeclaration const * pType); + AstType const * compose(AstDeclaration const * pDecl); +private: + AstDeclaration* m_pComplexPart; + ::rtl::OString m_name; + DeclaratorType m_declType; +}; + +typedef ::std::list< FeDeclarator* > FeDeclList; + +class FeInheritanceHeader +{ +public: + FeInheritanceHeader( + NodeType nodeType, ::rtl::OString* pName, ::rtl::OString* pInherits, + std::vector< rtl::OString > * typeParameters); + + virtual ~FeInheritanceHeader() + { + if ( m_pName ) + delete m_pName; + } + + NodeType getNodeType() + { return m_nodeType; } + ::rtl::OString* getName() + { return m_pName; } + AstDeclaration* getInherits() + { return m_pInherits; } + + std::vector< rtl::OString > const & getTypeParameters() const + { return m_typeParameters; } + +private: + void initializeInherits(::rtl::OString* pinherits); + + NodeType m_nodeType; + ::rtl::OString* m_pName; + AstDeclaration* m_pInherits; + std::vector< rtl::OString > m_typeParameters; +}; + +#endif // _IDLC_FEHELPER_HXX_ + diff --git a/idlc/inc/idlc/idlc.hxx b/idlc/inc/idlc/idlc.hxx new file mode 100644 index 000000000000..cec8e58900fb --- /dev/null +++ b/idlc/inc/idlc/idlc.hxx @@ -0,0 +1,168 @@ +/************************************************************************* + * + * 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 _IDLC_IDLC_HXX_ +#define _IDLC_IDLC_HXX_ + +#include <idlc/idlctypes.hxx> +#include <idlc/aststack.hxx> +#include <idlc/options.hxx> + +#ifdef SAL_UNX +#define SEPARATOR '/' +#define PATH_SEPARATOR "/" +#else +#define SEPARATOR '\\' +#define PATH_SEPARATOR "\\" +#endif + +class AstInterface; +class AstModule; +class AstType; +class Options; +class ErrorHandler; + +class Idlc +{ +public: + Idlc(Options* pOptions); + virtual ~Idlc(); + + void init(); + + Options* getOptions() + { return m_pOptions; } + AstStack* scopes() + { return m_pScopes; } + AstModule* getRoot() + { return m_pRoot; } + ErrorHandler* error() + { return m_pErrorHandler; } + const ::rtl::OString& getFileName() + { return m_fileName; } + void setFileName(const ::rtl::OString& fileName) + { m_fileName = fileName; } + const ::rtl::OString& getMainFileName() + { return m_mainFileName; } + void setMainFileName(const ::rtl::OString& mainFileName) + { m_mainFileName = mainFileName; } + const ::rtl::OString& getRealFileName() + { return m_realFileName; } + void setRealFileName(const ::rtl::OString& realFileName) + { m_realFileName = realFileName; } + const ::rtl::OString& getDocumentation() + { + m_bIsDocValid = sal_False; + return m_documentation; + } + void setDocumentation(const ::rtl::OString& documentation) + { + m_documentation = documentation; + m_bIsDocValid = sal_True; + } + sal_Bool isDocValid(); + sal_Bool isInMainFile() + { return m_bIsInMainfile; } + void setInMainfile(sal_Bool bInMainfile) + { m_bIsInMainfile = bInMainfile; } + sal_uInt32 getErrorCount() + { return m_errorCount; } + void setErrorCount(sal_uInt32 errorCount) + { m_errorCount = errorCount; } + void incErrorCount() + { m_errorCount++; } + sal_uInt32 getWarningCount() + { return m_warningCount; } + void setWarningCount(sal_uInt32 warningCount) + { m_warningCount = warningCount; } + void incWarningCount() + { m_warningCount++; } + sal_uInt32 getLineNumber() + { return m_lineNumber; } + void setLineNumber(sal_uInt32 lineNumber) + { m_lineNumber = lineNumber; } + void incLineNumber() + { m_lineNumber++; } + ParseState getParseState() + { return m_parseState; } + void setParseState(ParseState parseState) + { m_parseState = parseState; } + + void insertInclude(const ::rtl::OString& inc) + { m_includes.insert(inc); } + StringSet* getIncludes() + { return &m_includes; } + + void setPublished(bool published) { m_published = published; } + bool isPublished() const { return m_published; } + + void reset(); +private: + Options* m_pOptions; + AstStack* m_pScopes; + AstModule* m_pRoot; + ErrorHandler* m_pErrorHandler; + ::rtl::OString m_fileName; + ::rtl::OString m_mainFileName; + ::rtl::OString m_realFileName; + ::rtl::OString m_documentation; + sal_Bool m_bIsDocValid; + sal_Bool m_bGenerateDoc; + sal_Bool m_bIsInMainfile; + bool m_published; + sal_uInt32 m_errorCount; + sal_uInt32 m_warningCount; + sal_uInt32 m_lineNumber; + ParseState m_parseState; + StringSet m_includes; +}; + +sal_Int32 compileFile(const ::rtl::OString * pathname); + // a null pathname means stdin +sal_Int32 produceFile(const ::rtl::OString& filenameBase); + // filenameBase is filename without ".idl" +void removeIfExists(const ::rtl::OString& pathname); + +::rtl::OString makeTempName(const ::rtl::OString& prefix, const ::rtl::OString& postfix); +sal_Bool copyFile(const ::rtl::OString* source, const ::rtl::OString& target); + // a null source means stdin + +sal_Bool isFileUrl(const ::rtl::OString& fileName); +::rtl::OString convertToAbsoluteSystemPath(const ::rtl::OString& fileName); +::rtl::OString convertToFileUrl(const ::rtl::OString& fileName); + +Idlc* SAL_CALL idlc(); +Idlc* SAL_CALL setIdlc(Options* pOptions); + +AstDeclaration const * resolveTypedefs(AstDeclaration const * type); + +AstDeclaration const * deconstructAndResolveTypedefs( + AstDeclaration const * type, sal_Int32 * rank); + +AstInterface const * resolveInterfaceTypedefs(AstType const * type); + +#endif // _IDLC_IDLC_HXX_ + diff --git a/idlc/inc/idlc/idlctypes.hxx b/idlc/inc/idlc/idlctypes.hxx new file mode 100644 index 000000000000..47eaa802b28d --- /dev/null +++ b/idlc/inc/idlc/idlctypes.hxx @@ -0,0 +1,266 @@ +/************************************************************************* + * + * 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 _IDLC_IDLCTYPES_HXX_ +#define _IDLC_IDLCTYPES_HXX_ + +#include <stdio.h> + +#include <hash_map> +#include <list> +#include <vector> +#include <set> +#include <sal/types.h> +#include <rtl/ustring.hxx> + +struct EqualString +{ + sal_Bool operator()(const ::rtl::OString& str1, const ::rtl::OString& str2) const + { + return (str1 == str2); + } +}; + +struct HashString +{ + sal_Int32 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); + } +}; + +typedef ::std::list< ::rtl::OString > StringList; +typedef ::std::vector< ::rtl::OString > StringVector; +typedef ::std::set< ::rtl::OString, LessString > StringSet; + +class AstExpression; +typedef ::std::list< AstExpression* > ExprList; + +class AstUnionLabel; +typedef ::std::list< AstUnionLabel* > LabelList; + +class AstDeclaration; + +typedef ::std::hash_map< ::rtl::OString, AstDeclaration*, HashString, EqualString > DeclMap; +typedef ::std::list< AstDeclaration* > DeclList; + +class AstScope; +AstDeclaration* SAL_CALL scopeAsDecl(AstScope* pScope); +AstScope* SAL_CALL declAsScope(AstDeclaration* pDecl); + +#ifdef _MSC_VER +#pragma warning( disable : 4541 ) +#endif + +// flags used for attributes, properties and services +#define AF_INVALID 0x0000 +#define AF_READONLY 0x0001 +#define AF_OPTIONAL 0x0002 +#define AF_MAYBEVOID 0x0004 +#define AF_BOUND 0x0008 +#define AF_CONSTRAINED 0x0010 +#define AF_TRANSIENT 0x0020 +#define AF_MAYBEAMBIGUOUS 0x0040 +#define AF_MAYBEDEFAULT 0x0080 +#define AF_REMOVEABLE 0x0100 +#define AF_ATTRIBUTE 0x0200 +#define AF_PROPERTY 0x0400 + +enum ParseState +{ + PS_NoState, + PS_TypeDeclSeen, // Seen complete typedef declaration + PS_ConstantDeclSeen, // Seen complete const declaration + PS_ExceptionDeclSeen, // Seen complete exception declaration + PS_InterfaceDeclSeen, // Seen complete interface declaration + PS_ServiceDeclSeen, // Seen complete service declaration + PS_SingletonDeclSeen, // Seen complete singleton declaration + PS_ModuleDeclSeen, // Seen complete module declaration + PS_AttributeDeclSeen, // Seen complete attribute declaration + PS_PropertyDeclSeen, // Seen complete property declaration + PS_OperationDeclSeen, // Seen complete operation declaration + PS_InterfaceInheritanceDeclSeen, // Seen complete interface inheritance decl + PS_ConstantsDeclSeen, // Seen complete constants declaration + + PS_ServiceSeen, // Seen a SERVICE keyword + PS_ServiceIDSeen, // Seen the service ID + PS_ServiceSqSeen, // '{' seen for service + PS_ServiceQsSeen, // '}' seen for service + PS_ServiceBodySeen, // Seen complete service body + PS_ServiceMemberSeen, // Seen a service member + PS_ServiceIFHeadSeen, // Seen an interface member header + PS_ServiceSHeadSeen, // Seen an service member header + + PS_SingletonSeen, // Seen a SINGLETON keyword + PS_SingletonIDSeen, // Seen the singleton ID + PS_SingletonSqSeen, // '{' seen for singleton + PS_SingletonQsSeen, // '}' seen for singleton + PS_SingletonBodySeen, // Seen complete singleton body + PS_SingletonMemberSeen, // Seen a singleton member + + PS_ModuleSeen, // Seen a MODULE keyword + PS_ModuleIDSeen, // Seen the module ID + PS_ModuleSqSeen, // '{' seen for module + PS_ModuleQsSeen, // '}' seen for module + PS_ModuleBodySeen, // Seen complete module body + + PS_ConstantsSeen, // Seen a CONSTANTS keyword + PS_ConstantsIDSeen, // Seen the constants ID + PS_ConstantsSqSeen, // '{' seen for constants + PS_ConstantsQsSeen, // '}' seen for constants + PS_ConstantsBodySeen, // Seen complete constants body + + PS_InterfaceSeen, // Seen an INTERFACE keyword + PS_InterfaceIDSeen, // Seen the interface ID + PS_InterfaceHeadSeen, // Seen the interface head + PS_InheritSpecSeen, // Seen a complete inheritance spec + PS_ForwardDeclSeen, // Forward interface decl seen + PS_InterfaceSqSeen, // '{' seen for interface + PS_InterfaceQsSeen, // '}' seen for interface + PS_InterfaceBodySeen, // Seen an interface body + PS_InheritColonSeen, // Seen ':' in inheritance list + + PS_SNListCommaSeen, // Seen ',' in list of scoped names + PS_ScopedNameSeen, // Seen a complete scoped name + PS_SN_IDSeen, // Seen an identifier as part of a scoped name + PS_ScopeDelimSeen, // Seen a scope delim as party of a scoped name + + PS_ConstSeen, // Seen a CONST keyword + PS_ConstTypeSeen, // Parsed the type of a constant + PS_ConstIDSeen, // Seen the constant ID + PS_ConstAssignSeen, // Seen the '=' + PS_ConstExprSeen, // Seen the constant value expression + + PS_TypedefSeen, // Seen a TYPEDEF keyword + PS_TypeSpecSeen, // Seen a complete type specification + PS_DeclaratorsSeen, // Seen a complete list of declarators + + PS_StructSeen, // Seen a STRUCT keyword + PS_StructHeaderSeen, // Seen struct header + PS_StructIDSeen, // Seen the struct ID + PS_StructSqSeen, // '{' seen for struct + PS_StructQsSeen, // '}' seen for struct + PS_StructBodySeen, // Seen complete body of struct decl + + PS_MemberTypeSeen, // Seen type of struct or except member + PS_MemberDeclsSeen, // Seen decls of struct or except members + PS_MemberDeclsCompleted,// Completed one struct or except member to ';' + + PS_UnionSeen, // Seen a UNION keyword + PS_UnionIDSeen, // Seen the union ID + PS_SwitchSeen, // Seen the SWITCH keyword + PS_SwitchOpenParSeen, // Seen the switch open par. + PS_SwitchTypeSeen, // Seen the switch type spec + PS_SwitchCloseParSeen, // Seen the switch close par. + PS_UnionSqSeen, // '{' seen for union + PS_UnionQsSeen, // '}' seen for union + PS_DefaultSeen, // Seen DEFAULT keyword + PS_UnionLabelSeen, // Seen label of union element + PS_LabelColonSeen, // Seen ':' of union branch label + PS_LabelExprSeen, // Seen expression of union branch label + PS_UnionElemSeen, // Seen a union element + PS_UnionElemCompleted, // Completed one union member up to ';' + PS_CaseSeen, // Seen a CASE keyword + PS_UnionElemTypeSeen, // Seen type spec for union element + PS_UnionElemDeclSeen, // Seen declarator for union element + PS_UnionBodySeen, // Seen completed union body + + PS_EnumSeen, // Seen an ENUM keyword + PS_EnumIDSeen, // Seen the enum ID + PS_EnumSqSeen, // Seen '{' for enum + PS_EnumQsSeen, // Seen '}' for enum + PS_EnumBodySeen, // Seen complete enum body + PS_EnumCommaSeen, // Seen ',' in list of enumerators + + PS_SequenceSeen, // Seen a SEQUENCE keyword + PS_SequenceSqSeen, // Seen '<' for sequence + PS_SequenceQsSeen, // Seen '>' for sequence + PS_SequenceTypeSeen, // Seen type decl for sequence + + PS_ArrayIDSeen, // Seen array ID + PS_ArrayTypeSeen, // Seen array type + PS_ArrayCompleted, // Seen completed array declaration + PS_DimSqSeen, // Seen '[' for array dimension + PS_DimQsSeen, // Seen ']' for array dimension + PS_DimExprSeen, // Seen size expression for array dimension + + + PS_FlagHeaderSeen, // Seen the attribute|property|interface member head + PS_AttrSeen, // Seen ATTRIBUTE keyword + PS_AttrTypeSeen, // Seen type decl for attribute + PS_AttrCompleted, // Seen complete attribute declaration + PS_ReadOnlySeen, // Seen READONLY keyword + PS_OptionalSeen, // Seen OPTIONAL keyword + PS_MayBeVoidSeen, // Seen MAYBEVOID yword + PS_BoundSeen, // Seen BOUND keyword + PS_ConstrainedSeen, // Seen CONSTRAINED keyword + PS_TransientSeen, // Seen TRANSIENT keyword + PS_MayBeAmbigiousSeen, // Seen MAYBEAMBIGIOUS keyword + PS_MayBeDefaultSeen, // Seen MAYBEDEFAULT keyword + PS_RemoveableSeen, // Seen REMOVEABLE keyword + + PS_PropertySeen, // Seen PROPERTY keyword + PS_PropertyTypeSeen, // Seen type decl for property + PS_PropertyCompleted, // Seen complete property declaration + + PS_ExceptSeen, // Seen EXCEPTION keyword + PS_ExceptHeaderSeen, // Seen exception header keyword + PS_ExceptIDSeen, // Seen exception identifier + PS_ExceptSqSeen, // Seen '{' for exception + PS_ExceptQsSeen, // Seen '}' for exception + PS_ExceptBodySeen, // Seen complete exception body + + PS_OpHeadSeen, // Seen the operation head + PS_OpTypeSeen, // Seen operation return type + PS_OpIDSeen, // Seen operation ID + PS_OpParsCompleted, // Completed operation param list + PS_OpCompleted, // Completed operation statement + PS_OpSqSeen, // Seen '(' for operation + PS_OpQsSeen, // Seen ')' for operation + PS_OpParCommaSeen, // Seen ',' in list of op params + PS_OpParDirSeen, // Seen parameter direction + PS_OpParTypeSeen, // Seen parameter type + PS_OpParDeclSeen, // Seen parameter declaration + PS_OpOnewaySeen, // Seen ONEWAY keyword + + PS_RaiseSeen, // Seen RAISES keyword + PS_RaiseSqSeen, // Seen '(' for RAISES + PS_RaiseQsSeen, // Seen ')' for RAISES + + PS_DeclsCommaSeen, // Seen ',' in declarators list + PS_DeclsDeclSeen // Seen complete decl in decls list +}; + +#endif // _IDLC_IDLCTYPES_HXX_ + diff --git a/idlc/inc/idlc/inheritedinterface.hxx b/idlc/inc/idlc/inheritedinterface.hxx new file mode 100644 index 000000000000..1d0ea6bf46b5 --- /dev/null +++ b/idlc/inc/idlc/inheritedinterface.hxx @@ -0,0 +1,61 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef INCLUDED_idlc_inc_idlc_inheritedinterface_hxx +#define INCLUDED_idlc_inc_idlc_inheritedinterface_hxx + +#include "idlc/idlc.hxx" + +#include "rtl/ustring.hxx" + +class AstInterface; +class AstType; + +class InheritedInterface { +public: + InheritedInterface( + AstType const * theInterface, bool theOptional, + rtl::OUString const & theDocumentation): + interface(theInterface), optional(theOptional), + documentation(theDocumentation) {} + + AstType const * getInterface() const { return interface; } + + AstInterface const * getResolved() const + { return resolveInterfaceTypedefs(interface); } + + bool isOptional() const { return optional; } + + rtl::OUString getDocumentation() const { return documentation; } + +private: + AstType const * interface; + bool optional; + rtl::OUString documentation; +}; + +#endif diff --git a/idlc/inc/idlc/options.hxx b/idlc/inc/idlc/options.hxx new file mode 100644 index 000000000000..7eba788a4ea9 --- /dev/null +++ b/idlc/inc/idlc/options.hxx @@ -0,0 +1,82 @@ +/************************************************************************* + * + * 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 _IDLC_OPTIONS_HXX_ +#define _IDLC_OPTIONS_HXX_ + +#ifndef _IDLC_IDLCTYPEs_HXX_ +#include <idlc/idlctypes.hxx> +#endif + +typedef ::std::hash_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(); + ~Options(); + + sal_Bool initOptions(int ac, char* av[], sal_Bool bCmdFile=sal_False) + throw( IllegalArgument ); + + ::rtl::OString prepareHelp(); + ::rtl::OString prepareVersion(); + + const ::rtl::OString& getProgramName() const; + sal_Bool isValid(const ::rtl::OString& option); + const ::rtl::OString getOption(const ::rtl::OString& option) + throw( IllegalArgument ); + + const StringVector& getInputFiles() const { return m_inputFiles; } + bool readStdin() const { return m_stdin; } + bool verbose() const { return m_verbose; } + bool quiet() const { return m_quiet; } + +protected: + ::rtl::OString m_program; + StringVector m_inputFiles; + bool m_stdin; + bool m_verbose; + bool m_quiet; + OptionMap m_options; +}; + +#endif // _IDLC_OPTIONS_HXX_ + diff --git a/idlc/inc/makefile.mk b/idlc/inc/makefile.mk new file mode 100644 index 000000000000..e912e1defb35 --- /dev/null +++ b/idlc/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=idlc +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/idlc/inc/pch/precompiled_idlc.cxx b/idlc/inc/pch/precompiled_idlc.cxx new file mode 100644 index 000000000000..6ff8144f4231 --- /dev/null +++ b/idlc/inc/pch/precompiled_idlc.cxx @@ -0,0 +1,29 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "precompiled_idlc.hxx" + diff --git a/idlc/inc/pch/precompiled_idlc.hxx b/idlc/inc/pch/precompiled_idlc.hxx new file mode 100644 index 000000000000..6a0ca40d1033 --- /dev/null +++ b/idlc/inc/pch/precompiled_idlc.hxx @@ -0,0 +1,32 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): Generated on 2006-09-01 17:49:49.748845 + +#ifdef PRECOMPILED_HEADERS +#endif + diff --git a/idlc/prj/build.lst b/idlc/prj/build.lst new file mode 100644 index 000000000000..84f2ee180bcd --- /dev/null +++ b/idlc/prj/build.lst @@ -0,0 +1,5 @@ +ic idlc : registry NULL +ic idlc usr1 - all ic_mkout NULL +ic idlc\inc nmake - all ic_inc NULL +ic idlc\source\preproc nmake - all ic_preproc ic_inc NULL +ic idlc\source nmake - all ic_source ic_inc NULL diff --git a/idlc/prj/d.lst b/idlc/prj/d.lst new file mode 100644 index 000000000000..edd0ecb33a35 --- /dev/null +++ b/idlc/prj/d.lst @@ -0,0 +1,7 @@ +..\%__SRC%\bin\idlc.exe %_DEST%\bin%_EXT%\idlc.exe +..\%__SRC%\bin\idlc.pdb %_DEST%\bin%_EXT%\idlc.pdb +..\%__SRC%\bin\idlcpp.exe %_DEST%\bin%_EXT%\idlcpp.exe +..\%__SRC%\bin\idlcpp.pdb %_DEST%\bin%_EXT%\idlcpp.pdb + +..\%__SRC%\bin\idlc %_DEST%\bin%_EXT%\idlc +..\%__SRC%\bin\idlcpp %_DEST%\bin%_EXT%\idlcpp diff --git a/idlc/source/astarray.cxx b/idlc/source/astarray.cxx new file mode 100644 index 000000000000..0277b5a04e76 --- /dev/null +++ b/idlc/source/astarray.cxx @@ -0,0 +1,74 @@ +/************************************************************************* + * + * 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_idlc.hxx" +#include <idlc/astarray.hxx> + +using namespace ::rtl; + +AstArray::AstArray(const OString& name, AstType* pType, const ExprList& rDimExpr, AstScope* pScope) + : AstType(NT_array, name, pScope) + , m_pType(pType) + , m_dimension((sal_uInt32)(rDimExpr.size())) + , m_dimExpressions(rDimExpr) +{ + if ( m_pType ) + setName(makeName()); +} + +AstArray::AstArray(AstType* pType, const ExprList& rDimExpr, AstScope* pScope) + : AstType(NT_array, OString("arrary_"), pScope) + , m_pType(pType) + , m_dimension((sal_uInt32)(rDimExpr.size())) + , m_dimExpressions(rDimExpr) +{ + if ( m_pType ) + setName(makeName()); +} + +OString AstArray::makeName() +{ + if ( m_pType ) + { + OString name(m_pType->getScopedName()); + OString openBracket("["); + OString closeBracket("]"); + ExprList::iterator iter = m_dimExpressions.begin(); + ExprList::iterator end = m_dimExpressions.end(); + + while ( iter != end ) + { + name += openBracket; + name += (*iter)->toString(); + name += closeBracket; + ++iter; + } + return name; + } + return OString(); +} diff --git a/idlc/source/astconstant.cxx b/idlc/source/astconstant.cxx new file mode 100644 index 000000000000..2f920508bd75 --- /dev/null +++ b/idlc/source/astconstant.cxx @@ -0,0 +1,136 @@ +/************************************************************************* + * + * 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_idlc.hxx" +#include <idlc/astconstant.hxx> +#include <idlc/astscope.hxx> + +#include "registry/writer.hxx" + +using namespace ::rtl; + +AstConstant::AstConstant(const ExprType type, + const NodeType nodeType, + AstExpression* pExpr, + const ::rtl::OString& name, + AstScope* pScope) + : AstDeclaration(nodeType, name, pScope) + , m_pConstValue(pExpr) + , m_constValueType(type) +{ +} + +AstConstant::AstConstant(const ExprType type, + AstExpression* pExpr, + const ::rtl::OString& name, + AstScope* pScope) + : AstDeclaration(NT_const, name, pScope) + , m_pConstValue(pExpr) + , m_constValueType(type) +{ +} + +AstConstant::~AstConstant() +{ + +} + +sal_Bool AstConstant::dumpBlob( + typereg::Writer & rBlob, sal_uInt16 index, bool published) +{ + RTConstValue aConst; + sal_Unicode* str = NULL; + + AstExprValue *exprVal = getConstValue()->getExprValue(); + switch (getConstValueType()) + { + case ET_short: + aConst.m_type = RT_TYPE_INT16; + aConst.m_value.aShort = exprVal->u.sval; + break; + case ET_ushort: + aConst.m_type = RT_TYPE_UINT16; + aConst.m_value.aUShort = exprVal->u.usval; + break; + case ET_long: + aConst.m_type = RT_TYPE_INT32; + aConst.m_value.aLong = exprVal->u.lval; + break; + case ET_ulong: + aConst.m_type = RT_TYPE_UINT32; + aConst.m_value.aULong = exprVal->u.ulval; + break; + case ET_hyper: + aConst.m_type = RT_TYPE_INT64; + aConst.m_value.aHyper = exprVal->u.hval; + break; + case ET_uhyper: + aConst.m_type = RT_TYPE_UINT64; + aConst.m_value.aUHyper = exprVal->u.uhval; + break; + case ET_float: + aConst.m_type = RT_TYPE_FLOAT; + aConst.m_value.aFloat = exprVal->u.fval; + break; + case ET_double: + aConst.m_type = RT_TYPE_DOUBLE; + aConst.m_value.aDouble = exprVal->u.dval; + break; + case ET_byte: + aConst.m_type = RT_TYPE_BYTE; + aConst.m_value.aByte = exprVal->u.byval; + break; + case ET_boolean: + aConst.m_type = RT_TYPE_BOOL; + aConst.m_value.aBool = exprVal->u.bval; + break; + default: + { + fprintf(stderr, "%s: exprtype to const type: cannot convert ExprType\n", + idlc()->getOptions()->getProgramName().getStr()); + return sal_False; + } + } + + OString name = getLocalName(); + + OUString type; + if ( getNodeType() != NT_enum_val ) + { + type = OStringToOUString(exprTypeToString(getConstValueType()), RTL_TEXTENCODING_UTF8); + } + + rBlob.setFieldData( + index, getDocumentation(), OUString(), + RT_ACCESS_CONST | (published ? RT_ACCESS_PUBLISHED : 0), + OStringToOUString(name, RTL_TEXTENCODING_UTF8), type, aConst); + if (str) + delete[] str; + + return sal_True; +} diff --git a/idlc/source/astdeclaration.cxx b/idlc/source/astdeclaration.cxx new file mode 100644 index 000000000000..16e153e696e1 --- /dev/null +++ b/idlc/source/astdeclaration.cxx @@ -0,0 +1,211 @@ +/************************************************************************* + * + * 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_idlc.hxx" +#include <idlc/astdeclaration.hxx> +#include <idlc/astscope.hxx> +#include <rtl/strbuf.hxx> + +using namespace ::rtl; + +static OString sGlobal("::"); + +static OString convertName(const OString& name) +{ + OStringBuffer nameBuffer(name.getLength()+1); + sal_Int32 nIndex = 0; + do + { + OString token( name.getToken( 0, ':', nIndex ) ); + if( token.getLength() ) + { + nameBuffer.append('/'); + nameBuffer.append( token ); + } + } while( nIndex != -1 ); + return nameBuffer.makeStringAndClear(); +} + +AstDeclaration::AstDeclaration(NodeType type, const OString& name, AstScope* pScope) + : m_localName(name) + , m_pScope(pScope) + , m_nodeType(type) + , m_bImported(sal_False) + , m_bIsAdded(sal_False) + , m_bInMainFile(sal_False) + , m_bPredefined(false) +{ + if ( m_pScope ) + { + AstDeclaration* pDecl = scopeAsDecl(m_pScope); + if (pDecl) + { + m_scopedName = pDecl->getScopedName(); + if (m_scopedName.getLength() > 0) + m_scopedName += sGlobal; + m_scopedName += m_localName; + } + } else + { + m_scopedName = m_localName; + } + m_fullName = convertName(m_scopedName); + + if ( idlc()->getFileName() == idlc()->getRealFileName() ) + { + m_fileName = idlc()->getMainFileName(); + m_bInMainFile = sal_True; + } else + { + m_fileName = idlc()->getFileName(); + m_bImported = sal_True; + } + + if ( idlc()->isDocValid() ) + m_documentation = OStringToOUString(idlc()->getDocumentation(), RTL_TEXTENCODING_UTF8); + + m_bPublished = idlc()->isPublished(); +} + + +AstDeclaration::~AstDeclaration() +{ + +} + +void AstDeclaration::setPredefined(bool bPredefined) +{ + m_bPredefined = bPredefined; + if ( m_bPredefined ) + { + m_fileName = OString(); + m_bInMainFile = sal_False; + } +} + +void AstDeclaration::setName(const ::rtl::OString& name) +{ + m_scopedName = name; + sal_Int32 nIndex = name.lastIndexOf( ':' ); + m_localName = name.copy( nIndex+1 ); + +// Huh ? There is always at least one token + +// sal_Int32 count = name.getTokenCount(':'); + +// if ( count > 0 ) +// { +// m_localName = name.getToken(count-1, ':'); +// m_scopedName = name; +// } else if ( m_pScope ) +// { +// m_localName = name; +// AstDeclaration* pDecl = scopeAsDecl(m_pScope); +// if (pDecl) +// { +// m_scopedName = pDecl->getScopedName(); +// if (m_scopedName.getLength() > 0) +// m_scopedName += sGlobal; +// m_scopedName += m_localName; +// } +// } else +// { +// m_localName = name; +// m_scopedName = name; +// } + m_fullName = convertName(m_scopedName); +} + +bool AstDeclaration::isType() const { + switch (m_nodeType) { + case NT_interface: + case NT_instantiated_struct: + case NT_union: + case NT_enum: + case NT_sequence: + case NT_array: + case NT_typedef: + case NT_predefined: + case NT_type_parameter: + return true; + + default: + OSL_ASSERT(m_nodeType != NT_struct); // see AstStruct::isType + return false; + } +} + +sal_Bool AstDeclaration::hasAncestor(AstDeclaration* pDecl) +{ + if (this == pDecl) + return sal_True; + if ( !m_pScope ) + return sal_False; + return scopeAsDecl(m_pScope)->hasAncestor(pDecl); +} + +sal_Bool AstDeclaration::dump(RegistryKey& rKey) +{ + AstScope* pScope = declAsScope(this); + sal_Bool bRet = sal_True; + + if ( pScope ) + { + DeclList::const_iterator iter = pScope->getIteratorBegin(); + DeclList::const_iterator end = pScope->getIteratorEnd(); + AstDeclaration* pDecl = NULL; + while ( iter != end && bRet) + { + pDecl = *iter; + if ( pDecl->isInMainfile() ) + { + switch ( pDecl->getNodeType() ) + { + case NT_module: + case NT_constants: + case NT_interface: + case NT_struct: + case NT_exception: + case NT_enum: + case NT_union: + case NT_typedef: + case NT_service: + case NT_singleton: + bRet = pDecl->dump(rKey); + break; + default: + break; + } + } + + ++iter; + } + } + return bRet; +} + diff --git a/idlc/source/astdump.cxx b/idlc/source/astdump.cxx new file mode 100644 index 000000000000..3934cfb67e19 --- /dev/null +++ b/idlc/source/astdump.cxx @@ -0,0 +1,454 @@ +/************************************************************************* + * + * 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_idlc.hxx" +#include <idlc/astmodule.hxx> +#include <idlc/asttypedef.hxx> +#include <idlc/astservice.hxx> +#include <idlc/astconstant.hxx> +#include <idlc/astattribute.hxx> +#include <idlc/astinterfacemember.hxx> +#ifndef _IDLC_ASTSERVICEEMEMBER_HXX_ +#include <idlc/astservicemember.hxx> +#endif +#include <idlc/astobserves.hxx> +#include <idlc/astneeds.hxx> +#include <idlc/astsequence.hxx> +#include "idlc/astoperation.hxx" + +#include "registry/version.h" +#include "registry/writer.hxx" + +using namespace ::rtl; + +sal_Bool AstModule::dump(RegistryKey& rKey) +{ + OUString emptyStr; + RegistryKey localKey; + if ( getNodeType() == NT_root ) + { + localKey = rKey; + }else + { + if (rKey.createKey( OStringToOUString(getFullName(), RTL_TEXTENCODING_UTF8 ), localKey)) + { + fprintf(stderr, "%s: warning, could not create key '%s' in '%s'\n", + idlc()->getOptions()->getProgramName().getStr(), + getFullName().getStr(), OUStringToOString(rKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr()); + return sal_False; + } + } + + sal_uInt16 nConst = getNodeCount(NT_const); + + if ( nConst > 0 ) + { + RTTypeClass typeClass = RT_TYPE_MODULE; + if ( getNodeType() == NT_constants ) + typeClass = RT_TYPE_CONSTANTS; + + typereg::Writer aBlob( + m_bPublished ? TYPEREG_VERSION_1 : TYPEREG_VERSION_0, + getDocumentation(), emptyStr, typeClass, + m_bPublished, + OStringToOUString(getRelativName(), RTL_TEXTENCODING_UTF8), 0, + nConst, 0, 0); + + DeclList::const_iterator iter = getIteratorBegin(); + DeclList::const_iterator end = getIteratorEnd(); + AstDeclaration* pDecl = NULL; + sal_uInt16 index = 0; + while ( iter != end ) + { + pDecl = *iter; + if ( pDecl->getNodeType() == NT_const && + pDecl->isInMainfile() ) + { + ((AstConstant*)pDecl)->dumpBlob( + aBlob, index++, + getNodeType() == NT_module && pDecl->isPublished()); + } + ++iter; + } + + sal_uInt32 aBlobSize; + void const * pBlob = aBlob.getBlob(&aBlobSize); + + if (localKey.setValue(emptyStr, RG_VALUETYPE_BINARY, + (RegValue)pBlob, aBlobSize)) + { + fprintf(stderr, "%s: warning, could not set value of key \"%s\" in %s\n", + idlc()->getOptions()->getProgramName().getStr(), + getFullName().getStr(), OUStringToOString(localKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr()); + return sal_False; + } + } else + { + RTTypeClass typeClass = RT_TYPE_MODULE; + if ( getNodeType() == NT_constants ) + typeClass = RT_TYPE_CONSTANTS; + + typereg::Writer aBlob( + m_bPublished ? TYPEREG_VERSION_1 : TYPEREG_VERSION_0, + getDocumentation(), emptyStr, typeClass, m_bPublished, + OStringToOUString(getRelativName(), RTL_TEXTENCODING_UTF8), 0, 0, 0, + 0); + + sal_uInt32 aBlobSize; + void const * pBlob = aBlob.getBlob(&aBlobSize); + + if ( getNodeType() != NT_root ) + { + if (localKey.setValue(emptyStr, RG_VALUETYPE_BINARY, + (RegValue)pBlob, aBlobSize)) + { + fprintf(stderr, "%s: warning, could not set value of key \"%s\" in %s\n", + idlc()->getOptions()->getProgramName().getStr(), + getFullName().getStr(), OUStringToOString(localKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr()); + return sal_False; + } + } + } + if ( getNodeType() == NT_root ) + { + localKey.releaseKey(); + } + return AstDeclaration::dump(rKey); +} + +sal_Bool AstTypeDef::dump(RegistryKey& rKey) +{ + OUString emptyStr; + RegistryKey localKey; + if (rKey.createKey( OStringToOUString(getFullName(), RTL_TEXTENCODING_UTF8 ), localKey)) + { + fprintf(stderr, "%s: warning, could not create key '%s' in '%s'\n", + idlc()->getOptions()->getProgramName().getStr(), + getFullName().getStr(), OUStringToOString(rKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr()); + return sal_False; + } + + typereg::Writer aBlob( + m_bPublished ? TYPEREG_VERSION_1 : TYPEREG_VERSION_0, + getDocumentation(), emptyStr, RT_TYPE_TYPEDEF, m_bPublished, + OStringToOUString(getRelativName(), RTL_TEXTENCODING_UTF8), 1, 0, 0, 0); + aBlob.setSuperTypeName( + 0, + OStringToOUString( + getBaseType()->getRelativName(), RTL_TEXTENCODING_UTF8)); + + sal_uInt32 aBlobSize; + void const * pBlob = aBlob.getBlob(&aBlobSize); + + if (localKey.setValue(emptyStr, RG_VALUETYPE_BINARY, (RegValue)pBlob, aBlobSize)) + { + fprintf(stderr, "%s: warning, could not set value of key \"%s\" in %s\n", + idlc()->getOptions()->getProgramName().getStr(), + getFullName().getStr(), OUStringToOString(localKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr()); + return sal_False; + } + + return sal_True; +} + +sal_Bool AstService::dump(RegistryKey& rKey) +{ + OUString emptyStr; + typereg_Version version = m_bPublished + ? TYPEREG_VERSION_1 : TYPEREG_VERSION_0; + OString superName; + sal_uInt16 constructors = 0; + sal_uInt16 properties = 0; + sal_uInt16 references = 0; + {for (DeclList::const_iterator i(getIteratorBegin()); i != getIteratorEnd(); + ++i) + { + switch ((*i)->getNodeType()) { + case NT_interface: + case NT_typedef: + version = TYPEREG_VERSION_1; + OSL_ASSERT(superName.getLength() == 0); + superName = (*i)->getRelativName(); + break; + + case NT_operation: + OSL_ASSERT(getNodeType() == NT_service); + ++constructors; + break; + + case NT_property: + OSL_ASSERT(getNodeType() == NT_service); + ++properties; + break; + + case NT_service_member: + if (getNodeType() == NT_singleton) { + OSL_ASSERT(superName.getLength() == 0); + superName = ((AstServiceMember *)(*i))-> + getRealService()->getRelativName(); + break; + } + case NT_interface_member: + case NT_observes: + case NT_needs: + OSL_ASSERT(getNodeType() == NT_service); + ++references; + break; + + default: + OSL_ASSERT(false); + break; + } + }} + OSL_ASSERT(constructors == 0 || !m_defaultConstructor); + if (m_defaultConstructor) { + constructors = 1; + } + RegistryKey localKey; + if (rKey.createKey( + rtl::OStringToOUString(getFullName(), RTL_TEXTENCODING_UTF8), + localKey)) { + fprintf( + stderr, "%s: warning, could not create key '%s' in '%s'\n", + idlc()->getOptions()->getProgramName().getStr(), + getFullName().getStr(), + rtl::OUStringToOString( + rKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr()); + return false; + } + typereg::Writer writer( + version, getDocumentation(), emptyStr, + getNodeType() == NT_singleton ? RT_TYPE_SINGLETON : RT_TYPE_SERVICE, + m_bPublished, + rtl::OStringToOUString(getRelativName(), RTL_TEXTENCODING_UTF8), + superName.getLength() == 0 ? 0 : 1, properties, constructors, + references); + if (superName.getLength() != 0) { + writer.setSuperTypeName( + 0, rtl::OStringToOUString(superName, RTL_TEXTENCODING_UTF8)); + } + sal_uInt16 constructorIndex = 0; + sal_uInt16 propertyIndex = 0; + sal_uInt16 referenceIndex = 0; + {for (DeclList::const_iterator i(getIteratorBegin()); i != getIteratorEnd(); + ++i) + { + switch ((*i)->getNodeType()) { + case NT_operation: +// static_cast< AstOperation * >(*i)->dumpBlob( + ((AstOperation *)(*i))->dumpBlob( + writer, constructorIndex++); + break; + + case NT_property: +// static_cast< AstAttribute * >(*i)->dumpBlob( + ((AstAttribute *)(*i))->dumpBlob( + writer, propertyIndex++, 0); + break; + + case NT_interface_member: + { +// AstInterfaceMember * decl = static_cast< AstInterfaceMember *>(*i); + AstInterfaceMember * decl = (AstInterfaceMember *)(*i); + writer.setReferenceData( + referenceIndex++, decl->getDocumentation(), RT_REF_SUPPORTS, + (decl->isOptional() + ? RT_ACCESS_OPTIONAL : RT_ACCESS_INVALID), + rtl::OStringToOUString( + decl->getRealInterface()->getRelativName(), + RTL_TEXTENCODING_UTF8)); + break; + } + + case NT_service_member: + if (getNodeType() == NT_service) { +// AstServiceMember * decl = static_cast< AstServiceMember * >(*i); + AstServiceMember * decl = (AstServiceMember *)(*i); + writer.setReferenceData( + referenceIndex++, decl->getDocumentation(), RT_REF_EXPORTS, + (decl->isOptional() + ? RT_ACCESS_OPTIONAL : RT_ACCESS_INVALID), + rtl::OStringToOUString( + decl->getRealService()->getRelativName(), + RTL_TEXTENCODING_UTF8)); + } + break; + + case NT_observes: + { +// AstObserves * decl = static_cast< AstObserves * >(*i); + AstObserves * decl = (AstObserves *)(*i); + writer.setReferenceData( + referenceIndex++, decl->getDocumentation(), RT_REF_OBSERVES, + RT_ACCESS_INVALID, + rtl::OStringToOUString( + decl->getRealInterface()->getRelativName(), + RTL_TEXTENCODING_UTF8)); + break; + } + + case NT_needs: + { +// AstNeeds * decl = static_cast< AstNeeds * >(*i); + AstNeeds * decl = (AstNeeds *)(*i); + writer.setReferenceData( + referenceIndex++, decl->getDocumentation(), RT_REF_NEEDS, + RT_ACCESS_INVALID, + rtl::OStringToOUString( + decl->getRealService()->getRelativName(), + RTL_TEXTENCODING_UTF8)); + break; + } + + default: + OSL_ASSERT( + (*i)->getNodeType() == NT_interface + || (*i)->getNodeType() == NT_typedef); + break; + } + }} + if (m_defaultConstructor) { + writer.setMethodData( + constructorIndex++, emptyStr, RT_MODE_TWOWAY, + emptyStr, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("void")), + 0, 0); + } + sal_uInt32 size; + void const * blob = writer.getBlob(&size); + if (localKey.setValue( + emptyStr, RG_VALUETYPE_BINARY, const_cast< void * >(blob), + size)) + { + fprintf( + stderr, "%s: warning, could not set value of key \"%s\" in %s\n", + idlc()->getOptions()->getProgramName().getStr(), + getFullName().getStr(), + rtl::OUStringToOString( + localKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr()); + return false; + } + return true; +} + +sal_Bool AstAttribute::dumpBlob( + typereg::Writer & rBlob, sal_uInt16 index, sal_uInt16 * methodIndex) +{ + RTFieldAccess accessMode = RT_ACCESS_INVALID; + + if (isReadonly()) + { + accessMode |= RT_ACCESS_READONLY; + } else + { + accessMode |= RT_ACCESS_READWRITE; + } + if (isOptional()) + { + accessMode |= RT_ACCESS_OPTIONAL; + } + if (isBound()) + { + accessMode |= RT_ACCESS_BOUND; + } + if (isMayBeVoid()) + { + accessMode |= RT_ACCESS_MAYBEVOID; + } + if (isConstrained()) + { + accessMode |= RT_ACCESS_CONSTRAINED; + } + if (isTransient()) + { + accessMode |= RT_ACCESS_TRANSIENT; + } + if (isMayBeAmbiguous()) + { + accessMode |= RT_ACCESS_MAYBEAMBIGUOUS; + } + if (isMayBeDefault()) + { + accessMode |= RT_ACCESS_MAYBEDEFAULT; + } + if (isRemoveable()) + { + accessMode |= RT_ACCESS_REMOVEABLE; + } + + OUString name(OStringToOUString(getLocalName(), RTL_TEXTENCODING_UTF8)); + rBlob.setFieldData( + index, getDocumentation(), OUString(), accessMode, name, + OStringToOUString(getType()->getRelativName(), RTL_TEXTENCODING_UTF8), + RTConstValue()); + dumpExceptions( + rBlob, m_getDocumentation, m_getExceptions, RT_MODE_ATTRIBUTE_GET, + methodIndex); + dumpExceptions( + rBlob, m_setDocumentation, m_setExceptions, RT_MODE_ATTRIBUTE_SET, + methodIndex); + + return sal_True; +} + +void AstAttribute::dumpExceptions( + typereg::Writer & writer, rtl::OUString const & documentation, + DeclList const & exceptions, RTMethodMode flags, sal_uInt16 * methodIndex) +{ + if (!exceptions.empty()) { + OSL_ASSERT(methodIndex != 0); + sal_uInt16 idx = (*methodIndex)++; + // exceptions.size() <= SAL_MAX_UINT16 already checked in + // AstInterface::dump: + writer.setMethodData( + idx, documentation, flags, + OStringToOUString(getLocalName(), RTL_TEXTENCODING_UTF8), + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("void")), 0, + static_cast< sal_uInt16 >(exceptions.size())); + sal_uInt16 exceptionIndex = 0; + for (DeclList::const_iterator i(exceptions.begin()); + i != exceptions.end(); ++i) + { + writer.setMethodExceptionTypeName( + idx, exceptionIndex++, + rtl::OStringToOUString( + (*i)->getRelativName(), RTL_TEXTENCODING_UTF8)); + } + } +} + +const sal_Char* AstSequence::getRelativName() const +{ + if ( !m_pRelativName ) + { + m_pRelativName = new OString("[]"); + AstDeclaration const * pType = resolveTypedefs( m_pMemberType ); + *m_pRelativName += pType->getRelativName(); + } + + return m_pRelativName->getStr(); +} diff --git a/idlc/source/astenum.cxx b/idlc/source/astenum.cxx new file mode 100644 index 000000000000..365b166be568 --- /dev/null +++ b/idlc/source/astenum.cxx @@ -0,0 +1,125 @@ +/************************************************************************* + * + * 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_idlc.hxx" +#include <idlc/astenum.hxx> + +#include "registry/version.h" +#include "registry/writer.hxx" + +using namespace ::rtl; + +AstEnum::AstEnum(const ::rtl::OString& name, AstScope* pScope) + : AstType(NT_enum, name, pScope) + , AstScope(NT_enum) + , m_enumValueCount(0) +{ +} + +AstEnum::~AstEnum() +{ +} + +AstConstant* AstEnum::checkValue(AstExpression* pExpr) +{ + DeclList::const_iterator iter = getIteratorBegin(); + DeclList::const_iterator end = getIteratorEnd(); + AstConstant* pConst = NULL; + AstDeclaration* pDecl = NULL; + + while ( iter != end) + { + pDecl = *iter; + pConst = (AstConstant*)pDecl; + + if (pConst->getConstValue()->compare(pExpr)) + return pConst; + + ++iter; + } + + if ( pExpr->getExprValue()->u.lval > m_enumValueCount ) + m_enumValueCount = pExpr->getExprValue()->u.lval + 1; + + return NULL; +} + +sal_Bool AstEnum::dump(RegistryKey& rKey) +{ + RegistryKey localKey; + if (rKey.createKey( OStringToOUString(getFullName(), RTL_TEXTENCODING_UTF8 ), localKey)) + { + fprintf(stderr, "%s: warning, could not create key '%s' in '%s'\n", + idlc()->getOptions()->getProgramName().getStr(), + getFullName().getStr(), OUStringToOString(rKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr()); + return sal_False; + } + + OUString emptyStr; + sal_uInt16 nConst = getNodeCount(NT_enum_val); + if ( nConst > 0 ) + { + typereg::Writer aBlob( + m_bPublished ? TYPEREG_VERSION_1 : TYPEREG_VERSION_0, + getDocumentation(), emptyStr, RT_TYPE_ENUM, m_bPublished, + OStringToOUString(getRelativName(), RTL_TEXTENCODING_UTF8), 0, + nConst, 0, 0); + + DeclList::const_iterator iter = getIteratorBegin(); + DeclList::const_iterator end = getIteratorEnd(); + AstDeclaration* pDecl = NULL; + sal_uInt16 index = 0; + while ( iter != end ) + { + pDecl = *iter; + if ( pDecl->getNodeType() == NT_enum_val ) + ((AstConstant*)pDecl)->dumpBlob(aBlob, index++, false); + + ++iter; + } + + sal_uInt32 aBlobSize; + void const * pBlob = aBlob.getBlob(&aBlobSize); + + if (localKey.setValue(emptyStr, RG_VALUETYPE_BINARY, + (RegValue)pBlob, aBlobSize)) + { + fprintf(stderr, "%s: warning, could not set value of key \"%s\" in %s\n", + idlc()->getOptions()->getProgramName().getStr(), + getFullName().getStr(), OUStringToOString(localKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr()); + return sal_False; + } + } + + return sal_True; +} + +AstDeclaration* AstEnum::addDeclaration(AstDeclaration* pDecl) +{ + return AstScope::addDeclaration(pDecl); +} diff --git a/idlc/source/astexpression.cxx b/idlc/source/astexpression.cxx new file mode 100644 index 000000000000..a93c13ecf8ba --- /dev/null +++ b/idlc/source/astexpression.cxx @@ -0,0 +1,1266 @@ +/************************************************************************* + * + * 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_idlc.hxx" +#include <idlc/astexpression.hxx> +#include <idlc/astconstant.hxx> +#include <idlc/astscope.hxx> +#include <idlc/errorhandler.hxx> + +#include <limits.h> +#include <float.h> + +#undef MAXCHAR +#define MAXCHAR 127 +#undef MINCHAR +#define MINCHAR -128 + +using namespace ::rtl; + +AstExpression::AstExpression(ExprComb c, AstExpression *pExpr1, AstExpression *pExpr2) + : m_combOperator(c) + , m_subExpr1(pExpr1) + , m_subExpr2(pExpr2) + , m_exprValue(NULL) + , m_pSymbolicName(NULL) +{ + fillDefinitionDetails(); + +} + +AstExpression::AstExpression(sal_Int32 l) + : m_combOperator(EC_none) + , m_subExpr1(NULL) + , m_subExpr2(NULL) + , m_exprValue(NULL) + , m_pSymbolicName(NULL) +{ + fillDefinitionDetails(); + + m_exprValue = new AstExprValue(); + m_exprValue->et = ET_long; + m_exprValue->u.lval = l; +} + +AstExpression::AstExpression(sal_Int32 l, ExprType et) + : m_combOperator(EC_none) + , m_subExpr1(NULL) + , m_subExpr2(NULL) + , m_exprValue(NULL) + , m_pSymbolicName(NULL) +{ + fillDefinitionDetails(); + + m_exprValue = new AstExprValue(); + m_exprValue->et = et; + m_exprValue->u.lval = l; +} + +AstExpression::AstExpression(sal_Int64 h) + : m_combOperator(EC_none) + , m_subExpr1(NULL) + , m_subExpr2(NULL) + , m_exprValue(NULL) + , m_pSymbolicName(NULL) +{ + fillDefinitionDetails(); + + m_exprValue = new AstExprValue(); + m_exprValue->et = ET_hyper; + m_exprValue->u.hval = h; +} + +AstExpression::AstExpression(sal_uInt64 uh) + : m_combOperator(EC_none) + , m_subExpr1(NULL) + , m_subExpr2(NULL) + , m_exprValue(NULL) + , m_pSymbolicName(NULL) +{ + fillDefinitionDetails(); + + m_exprValue = new AstExprValue(); + m_exprValue->et = ET_uhyper; + m_exprValue->u.uhval = uh; +} + +AstExpression::AstExpression(double d) + : m_combOperator(EC_none) + , m_subExpr1(NULL) + , m_subExpr2(NULL) + , m_exprValue(NULL) + , m_pSymbolicName(NULL) +{ + fillDefinitionDetails(); + + m_exprValue = new AstExprValue(); + m_exprValue->et = ET_double; + m_exprValue->u.dval = d; +} + +AstExpression::AstExpression(::rtl::OString* scopedName) + : m_combOperator(EC_symbol) + , m_subExpr1(NULL) + , m_subExpr2(NULL) + , m_exprValue(NULL) + , m_pSymbolicName(scopedName) +{ + fillDefinitionDetails(); +} + +AstExpression::~AstExpression() +{ + if ( m_exprValue ) + delete m_exprValue; + if ( m_subExpr1 ) + delete m_subExpr1; + if ( m_subExpr2 ) + delete m_subExpr2; + if ( m_pSymbolicName ) + delete m_pSymbolicName; +} + +/* + * Perform the coercion from the given AstExprValue to the requested + * ExprType. Return an AstExprValue if successful, NULL if failed. + * must be done for hyper, uhyper + */ +static AstExprValue * +coerce_value(AstExprValue *ev, ExprType t) +{ + if (ev == NULL) + return NULL; + + switch (t) + { + case ET_short: + switch (ev->et) + { + case ET_short: + return ev; + case ET_ushort: + if (ev->u.usval > SAL_MAX_INT16) + return NULL; + ev->u.sval = (sal_Int16)ev->u.usval; + ev->et = ET_short; + return ev; + case ET_long: + if (ev->u.lval < SAL_MIN_INT16 || ev->u.lval > SAL_MAX_INT16) + return NULL; + ev->u.sval = (sal_Int16)ev->u.lval; + ev->et = ET_short; + return ev; + case ET_ulong: + if (ev->u.ulval > SAL_MAX_INT16) + return NULL; + ev->u.sval = (sal_Int16)ev->u.ulval; + ev->et = ET_short; + return ev; + case ET_hyper: + if (ev->u.hval < SAL_MIN_INT16 || ev->u.hval > SAL_MAX_INT16) + return NULL; + ev->u.sval = (sal_Int16)ev->u.hval; + ev->et = ET_short; + return ev; + case ET_uhyper: + if (ev->u.uhval > SAL_MAX_INT16) + return NULL; + ev->u.sval = (sal_Int16)ev->u.uhval; + ev->et = ET_short; + return ev; + case ET_boolean: + ev->u.sval = (sal_Int16)ev->u.bval; + ev->et = ET_short; + return ev; + case ET_float: + if (ev->u.fval < SAL_MIN_INT16 || ev->u.fval > SAL_MAX_INT16) + return NULL; + ev->u.sval = (sal_Int16)ev->u.fval; + ev->et = ET_short; + return ev; + case ET_double: + if (ev->u.dval < SAL_MIN_INT16 || ev->u.dval > SAL_MAX_INT16) + return NULL; + ev->u.sval = (sal_Int16)ev->u.dval; + ev->et = ET_short; + return ev; + case ET_byte: + ev->u.sval = (sal_Int16)ev->u.byval; + ev->et = ET_short; + return ev; + default: + OSL_ASSERT(false); + return NULL; + } + case ET_ushort: + switch (ev->et) + { + case ET_short: + if (ev->u.sval < 0) + return NULL; + ev->u.usval = (sal_uInt16)ev->u.sval; + ev->et = ET_ushort; + return ev; + case ET_ushort: + return ev; + case ET_long: + if (ev->u.lval < 0 || ev->u.lval > SAL_MAX_UINT16) + return NULL; + ev->u.usval = (sal_uInt16)ev->u.lval; + ev->et = ET_ushort; + return ev; + case ET_ulong: + if (ev->u.ulval > SAL_MAX_UINT16) + return NULL; + ev->u.usval = (sal_uInt16)ev->u.ulval; + ev->et = ET_ushort; + return ev; + case ET_hyper: + if (ev->u.hval < 0 || ev->u.hval > SAL_MAX_UINT16) + return NULL; + ev->u.usval = (sal_uInt16)ev->u.hval; + ev->et = ET_ushort; + return ev; + case ET_uhyper: + if (ev->u.uhval > SAL_MAX_UINT16) + return NULL; + ev->u.usval = (sal_uInt16)ev->u.uhval; + ev->et = ET_ushort; + return ev; + case ET_boolean: + ev->u.usval = (sal_uInt16)ev->u.bval; + ev->et = ET_short; + return ev; + case ET_float: + if (ev->u.fval < 0.0 || ev->u.fval > SAL_MAX_UINT16) + return NULL; + ev->u.usval = (sal_uInt16)ev->u.fval; + ev->et = ET_short; + return ev; + case ET_double: + if (ev->u.dval < 0.0 || ev->u.dval > SAL_MAX_UINT16) + return NULL; + ev->u.usval = (sal_uInt16)ev->u.dval; + ev->et = ET_short; + return ev; + case ET_byte: + ev->u.usval = (sal_uInt16)ev->u.byval; + ev->et = ET_ushort; + return ev; + default: + OSL_ASSERT(false); + return NULL; + } + case ET_long: + switch (ev->et) + { + case ET_short: + ev->u.lval = (sal_Int32)ev->u.sval; + ev->et = ET_long; + return ev; + case ET_ushort: + ev->u.lval = (sal_Int32)ev->u.usval; + ev->et = ET_long; + return ev; + case ET_long: + return ev; + case ET_ulong: + if (ev->u.ulval > SAL_MAX_INT32) + return NULL; + ev->u.lval = (sal_Int32)ev->u.ulval; + ev->et = ET_long; + return ev; + case ET_hyper: + if (ev->u.hval < SAL_MIN_INT32 || ev->u.hval > SAL_MAX_INT32) + return NULL; + ev->u.lval = (sal_Int32)ev->u.hval; + ev->et = ET_long; + return ev; + case ET_uhyper: + if (ev->u.uhval > SAL_MAX_INT32) + return NULL; + ev->u.lval = (sal_Int32)ev->u.uhval; + ev->et = ET_long; + return ev; + case ET_boolean: + ev->u.lval = (sal_Int32)ev->u.bval; + ev->et = ET_long; + return ev; + case ET_float: + if (ev->u.fval < SAL_MIN_INT32 || ev->u.fval > SAL_MAX_INT32) + return NULL; + ev->u.lval = (sal_Int32)ev->u.fval; + ev->et = ET_long; + return ev; + case ET_double: + if (ev->u.dval < SAL_MIN_INT32 || ev->u.dval > SAL_MAX_INT32) + return NULL; + ev->u.lval = (sal_Int32)ev->u.dval; + ev->et = ET_long; + return ev; + case ET_byte: + ev->u.lval = (sal_Int32) ev->u.byval; + ev->et = ET_long; + return ev; + default: + OSL_ASSERT(false); + return NULL; + } + case ET_ulong: + switch (ev->et) + { + case ET_short: + if (ev->u.sval < 0) + return NULL; + ev->u.ulval = (sal_uInt32)ev->u.sval; + ev->et = ET_ulong; + return ev; + case ET_ushort: + ev->u.ulval = (sal_uInt32)ev->u.usval; + ev->et = ET_ulong; + return ev; + case ET_long: + if (ev->u.lval < 0) + return NULL; + ev->u.ulval = (sal_uInt32)ev->u.lval; + ev->et = ET_ulong; + return ev; + case ET_ulong: + return ev; + case ET_hyper: + if (ev->u.hval < 0 || ev->u.hval > SAL_MAX_UINT32) + return NULL; + ev->u.lval = (sal_uInt32)ev->u.hval; + ev->et = ET_ulong; + return ev; + case ET_uhyper: + if (ev->u.uhval > SAL_MAX_UINT32) + return NULL; + ev->u.ulval = (sal_uInt32)ev->u.uhval; + ev->et = ET_ulong; + return ev; + case ET_boolean: + ev->u.ulval = (sal_uInt32)ev->u.bval; + ev->et = ET_ulong; + return ev; + case ET_float: + if (ev->u.fval < 0.0 || ev->u.fval > SAL_MAX_UINT32) + return NULL; + ev->u.ulval = (sal_uInt32)ev->u.fval; + ev->et = ET_ulong; + return ev; + case ET_double: + if (ev->u.dval < 0.0 || ev->u.dval > SAL_MAX_UINT32) + return NULL; + ev->u.ulval = (sal_uInt32)ev->u.dval; + ev->et = ET_ulong; + return ev; + case ET_byte: + ev->u.ulval = (sal_uInt32)ev->u.byval; + ev->et = ET_ulong; + return ev; + default: + OSL_ASSERT(false); + return NULL; + } + case ET_hyper: + switch (ev->et) + { + case ET_short: + ev->u.hval = (sal_Int64)ev->u.sval; + ev->et = ET_hyper; + return ev; + case ET_ushort: + ev->u.hval = (sal_Int64)ev->u.usval; + ev->et = ET_hyper; + return ev; + case ET_long: + ev->u.hval = (sal_Int64)ev->u.lval; + ev->et = ET_hyper; + return ev; + case ET_ulong: + ev->u.hval = (sal_Int64)ev->u.ulval; + ev->et = ET_hyper; + return ev; + case ET_hyper: + return ev; + case ET_uhyper: + if (ev->u.uhval > SAL_MAX_INT64) + return NULL; + ev->u.hval = (sal_Int64)ev->u.uhval; + ev->et = ET_long; + return ev; + case ET_boolean: + ev->u.hval = (sal_Int64)ev->u.bval; + ev->et = ET_hyper; + return ev; + case ET_float: + if (ev->u.fval < SAL_MIN_INT64 || ev->u.fval > SAL_MAX_INT64) + return NULL; + ev->u.hval = (sal_Int64)ev->u.fval; + ev->et = ET_hyper; + return ev; + case ET_double: + if (ev->u.dval < SAL_MIN_INT64 || ev->u.dval > SAL_MAX_INT64) + return NULL; + ev->u.hval = (sal_Int64)ev->u.dval; + ev->et = ET_hyper; + return ev; + case ET_byte: + ev->u.hval = (sal_Int64)ev->u.byval; + ev->et = ET_hyper; + return ev; + default: + OSL_ASSERT(false); + return NULL; + } + case ET_uhyper: + switch (ev->et) + { + case ET_short: + if (ev->u.sval < 0) + return NULL; + ev->u.uhval = (sal_uInt64)ev->u.sval; + ev->et = ET_uhyper; + return ev; + case ET_ushort: + ev->u.uhval = (sal_uInt64)ev->u.usval; + ev->et = ET_uhyper; + return ev; + case ET_long: + if (ev->u.lval < 0) + return NULL; + ev->u.uhval = (sal_uInt64)ev->u.lval; + ev->et = ET_uhyper; + return ev; + case ET_ulong: + ev->u.uhval = (sal_uInt64)ev->u.ulval; + ev->et = ET_uhyper; + return ev; + case ET_hyper: + if (ev->u.hval < 0) + return NULL; + ev->u.uhval = (sal_uInt64)ev->u.hval; + ev->et = ET_uhyper; + return ev; + case ET_uhyper: + return ev; + case ET_boolean: + ev->u.uhval = (sal_uInt64)ev->u.bval; + ev->et = ET_uhyper; + return ev; + case ET_float: + if (ev->u.fval < 0.0 || ev->u.fval > SAL_MAX_UINT64) + return NULL; + ev->u.uhval = (sal_uInt64)ev->u.fval; + ev->et = ET_uhyper; + return ev; + case ET_double: + if (ev->u.dval < 0.0 || ev->u.dval > SAL_MAX_UINT64) + return NULL; + ev->u.uhval = (sal_uInt64)ev->u.dval; + ev->et = ET_uhyper; + return ev; + case ET_byte: + ev->u.uhval = (sal_uInt64)ev->u.byval; + ev->et = ET_uhyper; + return ev; + default: + OSL_ASSERT(false); + return NULL; + } + case ET_boolean: + switch (ev->et) + { + case ET_short: + ev->u.bval = (ev->u.sval == 0) ? sal_False : sal_True; + ev->et = ET_boolean; + return ev; + case ET_ushort: + ev->u.bval = (ev->u.usval == 0) ? sal_False : sal_True; + ev->et = ET_boolean; + return ev; + case ET_long: + ev->u.bval = (ev->u.lval == 0) ? sal_False : sal_True; + ev->et = ET_boolean; + return ev; + case ET_ulong: + ev->u.bval = (ev->u.ulval == 0) ? sal_False : sal_True; + ev->et = ET_boolean; + return ev; + case ET_hyper: + ev->u.bval = (ev->u.hval == 0) ? sal_False : sal_True; + ev->et = ET_boolean; + return ev; + case ET_uhyper: + ev->u.bval = (ev->u.uhval == 0) ? sal_False : sal_True; + ev->et = ET_boolean; + return ev; + case ET_boolean: + return ev; + case ET_float: + ev->u.bval = (ev->u.fval == 0.0) ? sal_False : sal_True; + ev->et = ET_boolean; + return ev; + case ET_double: + ev->u.bval = (ev->u.dval == 0.0) ? sal_False : sal_True; + ev->et = ET_boolean; + return ev; + case ET_byte: + ev->u.bval = (ev->u.byval == 0) ? sal_False : sal_True; + ev->et = ET_boolean; + return ev; + default: + OSL_ASSERT(false); + return NULL; + } + case ET_float: + switch (ev->et) + { + case ET_short: + ev->u.fval = (float)ev->u.sval; + ev->et = ET_float; + return ev; + case ET_ushort: + ev->u.fval = (float)ev->u.usval; + ev->et = ET_float; + return ev; + case ET_long: + ev->u.fval = (float)ev->u.lval; + ev->et = ET_float; + return ev; + case ET_ulong: + ev->u.fval = (float)ev->u.ulval; + ev->et = ET_float; + return ev; + case ET_hyper: + ev->u.fval = (float)ev->u.hval; + ev->et = ET_float; + return ev; + case ET_uhyper: + if ((float)ev->u.ulval > FLT_MAX) + return NULL; + ev->u.fval = (float)ev->u.ulval; + ev->et = ET_float; + return ev; + case ET_boolean: + ev->u.fval = (ev->u.bval == sal_True) ? 1.0f : 0.0f; + ev->et = ET_float; + return ev; + case ET_float: + return ev; + case ET_double: + if ((float)ev->u.dval > FLT_MAX || (float)ev->u.dval < -FLT_MAX) + return NULL; + ev->u.fval = (float)ev->u.dval; + ev->et = ET_float; + return ev; + case ET_byte: + ev->u.fval = (float)ev->u.byval; + ev->et = ET_float; + return ev; + default: + OSL_ASSERT(false); + return NULL; + } + case ET_double: + switch (ev->et) + { + case ET_short: + ev->u.dval = (double)ev->u.sval; + ev->et = ET_double; + return ev; + case ET_ushort: + ev->u.dval = (double)ev->u.usval; + ev->et = ET_double; + return ev; + case ET_long: + ev->u.dval = (double)ev->u.lval; + ev->et = ET_double; + return ev; + case ET_ulong: + ev->u.dval = (double)ev->u.ulval; + ev->et = ET_double; + return ev; + case ET_hyper: + ev->u.dval = (double)ev->u.hval; + ev->et = ET_double; + return ev; + case ET_uhyper: + if ((double)ev->u.dval > FLT_MAX || (double)ev->u.dval < -FLT_MAX) + return NULL; + ev->u.dval = (double)ev->u.ulval; + ev->et = ET_double; + return ev; + case ET_boolean: + ev->u.dval = (ev->u.bval == sal_True) ? 1.0 : 0.0; + ev->et = ET_double; + return ev; + case ET_float: + ev->u.dval = (double)ev->u.fval; + ev->et = ET_double; + return ev; + case ET_double: + return ev; + case ET_byte: + ev->u.dval = (double)ev->u.byval; + ev->et = ET_double; + return ev; + default: + OSL_ASSERT(false); + return NULL; + } + case ET_byte: + switch (ev->et) + { + case ET_short: + if (ev->u.sval < SAL_MIN_INT8 || ev->u.sval > SAL_MAX_UINT8) + return NULL; + ev->u.byval = (sal_uChar)ev->u.sval; + ev->et = ET_byte; + return ev; + case ET_ushort: + if (ev->u.usval > SAL_MAX_UINT8) + return NULL; + ev->u.byval = (sal_uChar)ev->u.usval; + ev->et = ET_byte; + return ev; + case ET_long: + if (ev->u.lval < SAL_MIN_INT8 || ev->u.lval > SAL_MAX_UINT8) + return NULL; + ev->u.byval = (sal_uChar) ev->u.lval; + ev->et = ET_byte; + return ev; + case ET_ulong: + if (ev->u.ulval > SAL_MAX_UINT8) + return NULL; + ev->u.byval = (sal_uChar) ev->u.ulval; + ev->et = ET_byte; + return ev; + case ET_hyper: + if (ev->u.hval < SAL_MIN_INT8 || ev->u.hval > SAL_MAX_UINT8) + return NULL; + ev->u.byval = (sal_uChar) ev->u.hval; + ev->et = ET_byte; + return ev; + case ET_uhyper: + if (ev->u.uhval > SAL_MAX_UINT8) + return NULL; + ev->u.byval = (sal_uChar) ev->u.uhval; + ev->et = ET_byte; + return ev; + case ET_boolean: + ev->u.byval = (ev->u.bval == sal_False) ? 1 : 0; + ev->et = ET_byte; + return ev; + case ET_float: + if (ev->u.fval < SAL_MIN_INT8 || ev->u.fval > SAL_MAX_UINT8) + return NULL; + ev->u.byval = (sal_uChar) ev->u.fval; + ev->et = ET_byte; + return ev; + case ET_double: + if (ev->u.dval < SAL_MIN_INT8 || ev->u.dval > SAL_MAX_UINT8) + return NULL; + ev->u.byval = (sal_uChar) ev->u.dval; + ev->et = ET_byte; + return ev; + case ET_byte: + return ev; + default: + OSL_ASSERT(false); + return NULL; + } + default: + OSL_ASSERT(false); + return NULL; + } +} + +/* + * Evaluate the expression with the evaluation kind requested. Supported + * evaluation kinds are + * - EK_const: The expression must evaluate to a constant + * - EK_positive_int: The expression must further evaluate to a + * positive integer + */ +static AstExprValue * +eval_kind(AstExprValue *ev, EvalKind ek) +{ + if (ek == EK_const) + return ev; + if (ek == EK_positive_int) + return coerce_value(ev, ET_ulong); + + return NULL; +} + +AstExprValue* AstExpression::coerce(ExprType t, sal_Bool bAssign) +{ + AstExprValue *copy; + + /* + * Is it already of the right type? + */ + if (m_exprValue != NULL && m_exprValue->et == t) + return m_exprValue; + /* + * OK, must coerce + * + * First, evaluate it, then try to coerce result type + * If already evaluated, return the result + */ + m_exprValue = eval_internal(EK_const); + if (m_exprValue == NULL) + return NULL; + + /* + * Create a copy to contain coercion result + */ + copy = new AstExprValue; + + copy->et = m_exprValue->et; + switch (m_exprValue->et) + { + case ET_short: + copy->u.sval = m_exprValue->u.sval; + break; + case ET_ushort: + copy->u.usval = m_exprValue->u.usval; + break; + case ET_long: + copy->u.lval = m_exprValue->u.lval; + break; + case ET_ulong: + copy->u.ulval = m_exprValue->u.ulval; + break; + case ET_hyper: + copy->u.hval = m_exprValue->u.hval; + break; + case ET_uhyper: + copy->u.uhval = m_exprValue->u.uhval; + break; + case ET_boolean: + copy->u.bval = m_exprValue->u.bval; + break; + case ET_float: + copy->u.fval = m_exprValue->u.fval; + break; + case ET_double: + copy->u.dval = m_exprValue->u.dval; + break; + case ET_byte: + copy->u.byval = m_exprValue->u.byval; + break; + default: + OSL_ASSERT(false); + break; + } + + if (bAssign) + { + m_exprValue = coerce_value(copy, t); + return m_exprValue; + } + + return coerce_value(copy, t); +} + +void AstExpression::evaluate(EvalKind ek) +{ + m_exprValue = eval_internal(ek); + m_exprValue = eval_kind(m_exprValue, ek); +} + +sal_Bool AstExpression::operator==(AstExpression *pExpr) +{ + if (m_combOperator != pExpr->getCombOperator()) + return sal_False; + evaluate(EK_const); + pExpr->evaluate(EK_const); + if (m_exprValue == NULL || pExpr->getExprValue() == NULL) + return sal_False; + if (m_exprValue->et != pExpr->getExprValue()->et) + return sal_False; + switch (m_exprValue->et) + { + case ET_short: + return (m_exprValue->u.sval == pExpr->getExprValue()->u.sval) ? sal_True : sal_False; + case ET_ushort: + return (m_exprValue->u.usval == pExpr->getExprValue()->u.usval) ? sal_True : sal_False; + case ET_long: + return (m_exprValue->u.lval == pExpr->getExprValue()->u.lval) ? sal_True : sal_False; + case ET_ulong: + return (m_exprValue->u.ulval == pExpr->getExprValue()->u.ulval) ? sal_True : sal_False; + case ET_hyper: + return (m_exprValue->u.hval == pExpr->getExprValue()->u.hval) ? sal_True : sal_False; + case ET_uhyper: + return (m_exprValue->u.uhval == pExpr->getExprValue()->u.uhval) ? sal_True : sal_False; + case ET_float: + return (m_exprValue->u.fval == pExpr->getExprValue()->u.fval) ? sal_True : sal_False; + case ET_double: + return (m_exprValue->u.dval == pExpr->getExprValue()->u.dval) ? sal_True : sal_False; + case ET_byte: + return (m_exprValue->u.byval == pExpr->getExprValue()->u.byval) ? sal_True : sal_False; + case ET_boolean: + return (m_exprValue->u.lval == pExpr->getExprValue()->u.lval) ? sal_True : sal_False; + default: + OSL_ASSERT(false); + return sal_False; + } + + return sal_False; +} + +sal_Bool AstExpression::compare(AstExpression *pExpr) +{ + if (m_combOperator != pExpr->getCombOperator()) + return sal_False; + evaluate(EK_const); + pExpr->evaluate(EK_const); + if (m_exprValue == NULL || pExpr->getExprValue() == NULL) + return sal_False; + if (m_exprValue->et != pExpr->getExprValue()->et) + return sal_False; + switch (m_exprValue->et) + { + case ET_short: + return (m_exprValue->u.sval == pExpr->getExprValue()->u.sval) ? sal_True : sal_False; + case ET_ushort: + return (m_exprValue->u.usval == pExpr->getExprValue()->u.usval) ? sal_True : sal_False; + case ET_long: + return (m_exprValue->u.lval == pExpr->getExprValue()->u.lval) ? sal_True : sal_False; + case ET_ulong: + return (m_exprValue->u.ulval == pExpr->getExprValue()->u.ulval) ? sal_True : sal_False; + case ET_hyper: + return (m_exprValue->u.hval == pExpr->getExprValue()->u.hval) ? sal_True : sal_False; + case ET_uhyper: + return (m_exprValue->u.uhval == pExpr->getExprValue()->u.uhval) ? sal_True : sal_False; + case ET_float: + return (m_exprValue->u.fval == pExpr->getExprValue()->u.fval) ? sal_True : sal_False; + case ET_double: + return (m_exprValue->u.dval == pExpr->getExprValue()->u.dval) ? sal_True : sal_False; + case ET_byte: + return (m_exprValue->u.byval == pExpr->getExprValue()->u.byval) ? sal_True : sal_False; + case ET_boolean: + return (m_exprValue->u.lval == pExpr->getExprValue()->u.lval) ? sal_True : sal_False; + default: + OSL_ASSERT(false); + return sal_False; + } + + return sal_False; +} + +void AstExpression::fillDefinitionDetails() +{ + m_pScope = idlc()->scopes()->depth() > 0 ? idlc()->scopes()->top() : NULL; + m_lineNo = idlc()->getLineNumber(); + m_fileName = idlc()->getFileName(); +} + +AstExprValue* AstExpression::eval_internal(EvalKind ek) +{ + /* + * Already evaluated? + */ + if ( m_exprValue != NULL ) + return eval_kind(m_exprValue, ek); + /* + * OK, must evaluate operator + */ + switch (m_combOperator) + { + case EC_add: + case EC_minus: + case EC_mul: + case EC_div: + case EC_mod: + m_exprValue = eval_bin_op(ek); + return eval_kind(m_exprValue, ek); + case EC_or: + case EC_xor: + case EC_and: + case EC_left: + case EC_right: + m_exprValue = eval_bit_op(ek); + return eval_kind(m_exprValue, ek); + case EC_u_plus: + case EC_u_minus: + case EC_bit_neg: + m_exprValue = eval_un_op(ek); + return eval_kind(m_exprValue, ek); + case EC_symbol: + m_exprValue = eval_symbol(ek); + return eval_kind(m_exprValue, ek); + case EC_none: + return NULL; + } + + return NULL; +} + +AstExprValue* AstExpression::eval_bin_op(EvalKind ek) +{ + AstExprValue *retval = NULL; + ExprType eType = ET_double; + + if ( m_combOperator == EC_mod ) + eType = ET_hyper; + + if (ek != EK_const && ek != EK_positive_int) + return NULL; + if (m_subExpr1 == NULL || m_subExpr2 == NULL) + return NULL; + m_subExpr1->setExprValue(m_subExpr1->eval_internal(ek)); + if (m_subExpr1->getExprValue() == NULL) + return NULL; + m_subExpr1->setExprValue(m_subExpr1->coerce(eType)); + if (m_subExpr1->getExprValue() == NULL) + return NULL; + m_subExpr2->setExprValue(m_subExpr2->eval_internal(ek)); + if (m_subExpr2->getExprValue() == NULL) + return NULL; + m_subExpr2->setExprValue(m_subExpr2->coerce(eType)); + if (m_subExpr2->getExprValue() == NULL) + return NULL; + + retval = new AstExprValue(); + retval->et = eType; + + switch (m_combOperator) + { + case EC_mod: + if (m_subExpr2->getExprValue()->u.hval == 0) + return NULL; + retval->u.hval = m_subExpr1->getExprValue()->u.hval % m_subExpr2->getExprValue()->u.hval; + break; + case EC_add: + retval->u.dval = m_subExpr1->getExprValue()->u.dval + m_subExpr2->getExprValue()->u.dval; + break; + case EC_minus: + retval->u.dval = m_subExpr1->getExprValue()->u.dval - m_subExpr2->getExprValue()->u.dval; + break; + case EC_mul: + retval->u.dval = m_subExpr1->getExprValue()->u.dval * m_subExpr2->getExprValue()->u.dval; + break; + case EC_div: + if (m_subExpr2->getExprValue()->u.dval == 0.0) + return NULL; + retval->u.dval = m_subExpr1->getExprValue()->u.dval / m_subExpr2->getExprValue()->u.dval; + break; + default: + return NULL; + } + + return retval; +} + +AstExprValue* AstExpression::eval_bit_op(EvalKind ek) +{ + AstExprValue *retval = NULL; + + if (ek != EK_const && ek != EK_positive_int) + return NULL; + if (m_subExpr1 == NULL || m_subExpr2 == NULL) + return NULL; + m_subExpr1->setExprValue(m_subExpr1->eval_internal(ek)); + if (m_subExpr1->getExprValue() == NULL) + return NULL; + m_subExpr1->setExprValue(m_subExpr1->coerce(ET_long)); + if (m_subExpr1->getExprValue() == NULL) + return NULL; + m_subExpr2->setExprValue(m_subExpr2->eval_internal(ek)); + if (m_subExpr2->getExprValue() == NULL) + return NULL; + m_subExpr2->setExprValue(m_subExpr2->coerce(ET_long)); + if (m_subExpr2->getExprValue() == NULL) + return NULL; + + retval = new AstExprValue; + retval->et = ET_long; + + switch (m_combOperator) + { + case EC_or: + retval->u.lval = m_subExpr1->getExprValue()->u.lval | m_subExpr2->getExprValue()->u.lval; + break; + case EC_xor: + retval->u.lval = m_subExpr1->getExprValue()->u.lval ^ m_subExpr2->getExprValue()->u.lval; + break; + case EC_and: + retval->u.lval = m_subExpr1->getExprValue()->u.lval & m_subExpr2->getExprValue()->u.lval; + break; + case EC_left: + retval->u.lval = m_subExpr1->getExprValue()->u.lval << m_subExpr2->getExprValue()->u.lval; + break; + case EC_right: + retval->u.lval = m_subExpr1->getExprValue()->u.lval >> m_subExpr2->getExprValue()->u.lval; + break; + default: + return NULL; + } + + return retval; +} + +AstExprValue* AstExpression::eval_un_op(EvalKind ek) +{ + AstExprValue *retval = NULL; + + if (m_exprValue != NULL) + return m_exprValue; + + if (ek != EK_const && ek != EK_positive_int) + return NULL; + if (m_subExpr1 == NULL) + return NULL; + m_subExpr1->setExprValue(m_subExpr1->eval_internal(ek)); + if (m_subExpr1->getExprValue() == NULL) + return NULL; + m_subExpr1->setExprValue(m_subExpr1->coerce(ET_double)); + if (m_subExpr1->getExprValue() == NULL) + return NULL; + + retval = new AstExprValue(); + retval->et = ET_double; + + switch (m_combOperator) + { + case EC_u_plus: + retval->u.lval = m_subExpr1->getExprValue()->u.lval; + break; + case EC_u_minus: + retval->u.lval = -(m_subExpr1->getExprValue()->u.lval); + break; + case EC_bit_neg: + m_subExpr1->setExprValue(m_subExpr1->coerce(ET_long)); + if (m_subExpr1->getExprValue() == NULL) + return NULL; + retval->u.lval = ~m_subExpr1->getExprValue()->u.lval; + break; + default: + return NULL; + } + + return retval; +} + +AstExprValue* AstExpression::eval_symbol(EvalKind ek) +{ + AstScope *pScope = 0; + AstDeclaration *pDecl; + AstConstant *pConst; + + /* + * Is there a symbol stored? + */ + if (m_pSymbolicName == NULL) + { + idlc()->error()->evalError(this); + return NULL; + } + /* + * Get current scope for lookup + */ + if (idlc()->scopes()->depth() > 0) + pScope = idlc()->scopes()->topNonNull(); + if ( !pScope ) + { + idlc()->error()->lookupError(*m_pSymbolicName); + return NULL; + } + /* + * Do lookup + */ + pDecl = pScope->lookupByName(*m_pSymbolicName); + if (pDecl == NULL) + { + idlc()->error()->lookupError(*m_pSymbolicName); + return NULL; + } + /* + * Is it a constant? + */ + if (pDecl->getNodeType() != NT_const && + pDecl->getNodeType() != NT_enum_val) + { + idlc()->error()->constantExpected(pDecl, *m_pSymbolicName); + return NULL; + } + if (!idlc()->error()->checkPublished(pDecl)) + { + return NULL; + } + /* + * OK, now evaluate the constant we just got, to produce its value + */ + pConst = static_cast< AstConstant* >(pDecl); + if (pConst == NULL) + return NULL; + return pConst->getConstValue()->eval_internal(ek); +} + +OString AstExpression::toString() +{ + OString exprStr; + if ( m_combOperator == EC_symbol ) + return *m_pSymbolicName; + + if ( m_exprValue ) + { + switch (m_exprValue->et) + { + case ET_short: + return OString::valueOf((sal_Int32)m_exprValue->u.sval); + case ET_ushort: + return OString::valueOf((sal_Int32)m_exprValue->u.usval); + case ET_long: + return OString::valueOf(m_exprValue->u.lval); + case ET_ulong: + return OString::valueOf((sal_Int32)m_exprValue->u.ulval); + case ET_hyper: + return OString::valueOf(m_exprValue->u.hval); + case ET_uhyper: + return OString::valueOf((sal_Int64)m_exprValue->u.uhval); + case ET_float: + return OString::valueOf(m_exprValue->u.fval); + case ET_double: + return OString::valueOf(m_exprValue->u.dval); + case ET_byte: + return OString::valueOf((sal_Int32)m_exprValue->u.byval); + case ET_boolean: + if ( m_exprValue->u.lval == 0) + return OString("FALSE"); + else + return OString("TRUE"); + default: + OSL_ASSERT(false); + return OString(); + } + } + + switch (m_combOperator) + { + case EC_u_plus: + exprStr += OString("+"); + break; + case EC_u_minus: + exprStr += OString("-"); + break; + case EC_bit_neg: + exprStr += OString("~"); + break; + default: + break; + } + if ( m_subExpr1 ) + exprStr += m_subExpr1->toString(); + switch (m_combOperator) + { + case EC_add: + exprStr += OString(" + "); + break; + case EC_minus: + exprStr += OString(" - "); + break; + case EC_mul: + exprStr += OString(" * "); + break; + case EC_div: + exprStr += OString(" / "); + break; + case EC_mod: + exprStr += OString(" % "); + break; + case EC_or: + exprStr += OString(" | "); + break; + case EC_xor: + exprStr += OString(" ^ "); + break; + case EC_and: + exprStr += OString(" & "); + break; + case EC_left: + exprStr += OString(" << "); + break; + case EC_right: + exprStr += OString(" >> "); + break; + default: + break; + } + + if ( m_subExpr2 ) + exprStr += m_subExpr2->toString(); + + return exprStr; +} + +// Convert the type of an AST_Expression to a char * +const sal_Char* SAL_CALL exprTypeToString(ExprType t) +{ + switch (t) + { + case ET_short: + return "short"; + case ET_ushort: + return "unsigned short"; + case ET_long: + return "long"; + case ET_ulong: + return "unsigned long"; + case ET_hyper: + return "hyper"; + case ET_uhyper: + return "unsigned hyper"; + case ET_float: + return "float"; + case ET_double: + return "double"; + case ET_char: + return "char"; + case ET_byte: + return "byte"; + case ET_boolean: + return "boolean"; + case ET_string: + return "string"; + case ET_any: + return "any"; + case ET_type: + return "type"; + case ET_void: + return "void"; + case ET_none: + return "none"; + } + + return ("unkown"); +} diff --git a/idlc/source/astinterface.cxx b/idlc/source/astinterface.cxx new file mode 100644 index 000000000000..97bea094c53c --- /dev/null +++ b/idlc/source/astinterface.cxx @@ -0,0 +1,427 @@ +/************************************************************************* + * + * 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_idlc.hxx" +#include <idlc/astinterface.hxx> +#include <idlc/astattribute.hxx> +#include <idlc/astoperation.hxx> +#include "idlc/idlc.hxx" + +#include "registry/version.h" +#include "registry/writer.hxx" + +using namespace ::rtl; + +AstInterface::AstInterface(const ::rtl::OString& name, + AstInterface const * pInherits, + AstScope* pScope) + : AstType(NT_interface, name, pScope) + , AstScope(NT_interface) + , m_mandatoryInterfaces(0) + , m_bIsDefined(false) + , m_bForwarded(sal_False) + , m_bForwardedInSameFile(sal_False) + , m_bSingleInheritance(pInherits != 0) +{ + if (pInherits != 0) { + addInheritedInterface(pInherits, false, rtl::OUString()); + } +} + +AstInterface::~AstInterface() +{ +} + +AstInterface::DoubleDeclarations AstInterface::checkInheritedInterfaceClashes( + AstInterface const * ifc, bool optional) const +{ + DoubleDeclarations doubleDecls; + std::set< rtl::OString > seen; + checkInheritedInterfaceClashes( + doubleDecls, seen, ifc, true, optional, optional); + return doubleDecls; +} + +void AstInterface::addInheritedInterface( + AstType const * ifc, bool optional, rtl::OUString const & documentation) +{ + m_inheritedInterfaces.push_back( + InheritedInterface(ifc, optional, documentation)); + if (!optional) { + ++m_mandatoryInterfaces; + } + AstInterface const * resolved = resolveInterfaceTypedefs(ifc); + addVisibleInterface(resolved, true, optional); + if (optional) { + addOptionalVisibleMembers(resolved); + } +} + +AstInterface::DoubleMemberDeclarations AstInterface::checkMemberClashes( + AstDeclaration const * member) const +{ + DoubleMemberDeclarations doubleMembers; + checkMemberClashes(doubleMembers, member, true); + return doubleMembers; +} + +void AstInterface::addMember(AstDeclaration /*TODO: const*/ * member) { + addDeclaration(member); + m_visibleMembers.insert( + VisibleMembers::value_type( + member->getLocalName(), VisibleMember(member))); +} + +void AstInterface::forwardDefined(AstInterface const & def) +{ + setImported(def.isImported()); + setInMainfile(def.isInMainfile()); + setLineNumber(def.getLineNumber()); + setFileName(def.getFileName()); + setDocumentation(def.getDocumentation()); + m_inheritedInterfaces = def.m_inheritedInterfaces; + m_mandatoryInterfaces = def.m_mandatoryInterfaces; + m_bIsDefined = true; +} + +sal_Bool AstInterface::dump(RegistryKey& rKey) +{ + if ( !isDefined() ) + return sal_True; + + RegistryKey localKey; + if (rKey.createKey( OStringToOUString(getFullName(), RTL_TEXTENCODING_UTF8 ), localKey)) + { + fprintf(stderr, "%s: warning, could not create key '%s' in '%s'\n", + idlc()->getOptions()->getProgramName().getStr(), + getFullName().getStr(), OUStringToOString(rKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr()); + return sal_False; + } + + if (m_mandatoryInterfaces > SAL_MAX_UINT16 + || m_inheritedInterfaces.size() - m_mandatoryInterfaces + > SAL_MAX_UINT16) + { + fprintf( + stderr, "%s: interface %s has too many direct base interfaces\n", + idlc()->getOptions()->getProgramName().getStr(), + getScopedName().getStr()); + return false; + } + sal_uInt16 nBaseTypes = static_cast< sal_uInt16 >(m_mandatoryInterfaces); + sal_uInt16 nAttributes = 0; + sal_uInt16 nMethods = 0; + sal_uInt16 nReferences = static_cast< sal_uInt16 >( + m_inheritedInterfaces.size() - m_mandatoryInterfaces); + typereg_Version version + = (nBaseTypes <= 1 && nReferences == 0 && !m_bPublished + ? TYPEREG_VERSION_0 : TYPEREG_VERSION_1); + {for (DeclList::const_iterator i(getIteratorBegin()); i != getIteratorEnd(); + ++i) + { + switch ((*i)->getNodeType()) { + case NT_attribute: + { + if (!increment(&nAttributes, "attributes")) { + return false; + } +// AstAttribute * attr = static_cast< AstAttribute * >(*i); + AstAttribute * attr = (AstAttribute *)(*i); + if (attr->isBound()) { + version = TYPEREG_VERSION_1; + } + DeclList::size_type getCount = attr->getGetExceptionCount(); + if (getCount > SAL_MAX_UINT16) { + fprintf( + stderr, + ("%s: raises clause of getter for attribute %s of" + " interface %s is too long\n"), + idlc()->getOptions()->getProgramName().getStr(), + (*i)->getLocalName().getStr(), + getScopedName().getStr()); + return false; + } + if (getCount > 0) { + version = TYPEREG_VERSION_1; + if (!increment(&nMethods, "attributes")) { + return false; + } + } + DeclList::size_type setCount = attr->getSetExceptionCount(); + if (setCount > SAL_MAX_UINT16) { + fprintf( + stderr, + ("%s: raises clause of setter for attribute %s of" + " interface %s is too long\n"), + idlc()->getOptions()->getProgramName().getStr(), + (*i)->getLocalName().getStr(), + getScopedName().getStr()); + return false; + } + if (setCount > 0) { + version = TYPEREG_VERSION_1; + if (!increment(&nMethods, "attributes")) { + return false; + } + } + break; + } + + case NT_operation: + if (!increment(&nMethods, "methods")) { + return false; + } + break; + + default: + OSL_ASSERT(false); + break; + } + }} + + OUString emptyStr; + typereg::Writer aBlob( + version, getDocumentation(), emptyStr, RT_TYPE_INTERFACE, m_bPublished, + OStringToOUString(getRelativName(), RTL_TEXTENCODING_UTF8), nBaseTypes, + nAttributes, nMethods, nReferences); + + sal_uInt16 superTypeIndex = 0; + sal_uInt16 referenceIndex = 0; + {for (InheritedInterfaces::iterator i = m_inheritedInterfaces.begin(); + i != m_inheritedInterfaces.end(); ++i) + { + if (i->isOptional()) { + aBlob.setReferenceData( + referenceIndex++, i->getDocumentation(), RT_REF_SUPPORTS, + RT_ACCESS_OPTIONAL, + OStringToOUString( + i->getInterface()->getRelativName(), + RTL_TEXTENCODING_UTF8)); + } else { + aBlob.setSuperTypeName( + superTypeIndex++, + OStringToOUString( + i->getInterface()->getRelativName(), + RTL_TEXTENCODING_UTF8)); + } + }} + + sal_uInt16 attributeIndex = 0; + sal_uInt16 methodIndex = 0; + {for (DeclList::const_iterator i(getIteratorBegin()); i != getIteratorEnd(); + ++i) + { + switch ((*i)->getNodeType()) { + case NT_attribute: +// static_cast< AstAttribute * >(*i)->dumpBlob( + + ((AstAttribute *)(*i))->dumpBlob( + aBlob, attributeIndex++, &methodIndex); + break; + + case NT_operation: +// static_cast< AstOperation * >(*i)->dumpBlob(aBlob, methodIndex++); + ((AstOperation *)(*i))->dumpBlob(aBlob, methodIndex++); + break; + + default: + OSL_ASSERT(false); + break; + } + }} + + sal_uInt32 aBlobSize; + void const * pBlob = aBlob.getBlob(&aBlobSize); + + if (localKey.setValue(emptyStr, RG_VALUETYPE_BINARY, (RegValue)pBlob, aBlobSize)) + { + fprintf(stderr, "%s: warning, could not set value of key \"%s\" in %s\n", + idlc()->getOptions()->getProgramName().getStr(), + getFullName().getStr(), OUStringToOString(localKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr()); + return sal_False; + } + + return true; +} + +void AstInterface::checkInheritedInterfaceClashes( + DoubleDeclarations & doubleDeclarations, + std::set< rtl::OString > & seenInterfaces, AstInterface const * ifc, + bool direct, bool optional, bool mainOptional) const +{ + if (direct || optional + || seenInterfaces.insert(ifc->getScopedName()).second) + { + VisibleInterfaces::const_iterator visible( + m_visibleInterfaces.find(ifc->getScopedName())); + if (visible != m_visibleInterfaces.end()) { + switch (visible->second) { + case INTERFACE_INDIRECT_OPTIONAL: + if (direct && optional) { + doubleDeclarations.interfaces.push_back(ifc); + return; + } + break; + + case INTERFACE_DIRECT_OPTIONAL: + if (direct || !mainOptional) { + doubleDeclarations.interfaces.push_back(ifc); + } + return; + + case INTERFACE_INDIRECT_MANDATORY: + if (direct) { + doubleDeclarations.interfaces.push_back(ifc); + } + return; + + case INTERFACE_DIRECT_MANDATORY: + if (direct || (!optional && !mainOptional)) { + doubleDeclarations.interfaces.push_back(ifc); + } + return; + } + } + if (direct || !optional) { + {for (DeclList::const_iterator i(ifc->getIteratorBegin()); + i != ifc->getIteratorEnd(); ++i) + { + checkMemberClashes( + doubleDeclarations.members, *i, !mainOptional); + }} + {for (InheritedInterfaces::const_iterator i( + ifc->m_inheritedInterfaces.begin()); + i != ifc->m_inheritedInterfaces.end(); ++i) + { + checkInheritedInterfaceClashes( + doubleDeclarations, seenInterfaces, i->getResolved(), + false, i->isOptional(), mainOptional); + }} + } + } +} + +void AstInterface::checkMemberClashes( + DoubleMemberDeclarations & doubleMembers, AstDeclaration const * member, + bool checkOptional) const +{ + VisibleMembers::const_iterator i( + m_visibleMembers.find(member->getLocalName())); + if (i != m_visibleMembers.end()) { + if (i->second.mandatory != 0) { + if (i->second.mandatory->getScopedName() != member->getScopedName()) + { + DoubleMemberDeclaration d; + d.first = i->second.mandatory; + d.second = member; + doubleMembers.push_back(d); + } + } else if (checkOptional) { + for (VisibleMember::Optionals::const_iterator j( + i->second.optionals.begin()); + j != i->second.optionals.end(); ++j) + { + if (j->second->getScopedName() != member->getScopedName()) { + DoubleMemberDeclaration d; + d.first = j->second; + d.second = member; + doubleMembers.push_back(d); + } + } + } + } +} + +void AstInterface::addVisibleInterface( + AstInterface const * ifc, bool direct, bool optional) +{ + InterfaceKind kind = optional + ? direct ? INTERFACE_DIRECT_OPTIONAL : INTERFACE_INDIRECT_OPTIONAL + : direct ? INTERFACE_DIRECT_MANDATORY : INTERFACE_INDIRECT_MANDATORY; + std::pair< VisibleInterfaces::iterator, bool > result( + m_visibleInterfaces.insert( + VisibleInterfaces::value_type(ifc->getScopedName(), kind))); + bool seen = !result.second + && result.first->second >= INTERFACE_INDIRECT_MANDATORY; + if (!result.second && kind > result.first->second) { + result.first->second = kind; + } + if (!optional && !seen) { + {for (DeclList::const_iterator i(ifc->getIteratorBegin()); + i != ifc->getIteratorEnd(); ++i) + { + m_visibleMembers.insert( + VisibleMembers::value_type( + (*i)->getLocalName(), VisibleMember(*i))); + }} + {for (InheritedInterfaces::const_iterator i( + ifc->m_inheritedInterfaces.begin()); + i != ifc->m_inheritedInterfaces.end(); ++i) + { + addVisibleInterface(i->getResolved(), false, i->isOptional()); + }} + } +} + +void AstInterface::addOptionalVisibleMembers(AstInterface const * ifc) { + {for (DeclList::const_iterator i(ifc->getIteratorBegin()); + i != ifc->getIteratorEnd(); ++i) + { + VisibleMembers::iterator visible( + m_visibleMembers.find((*i)->getLocalName())); + if (visible == m_visibleMembers.end()) { + visible = m_visibleMembers.insert( + VisibleMembers::value_type( + (*i)->getLocalName(), VisibleMember())).first; + } + if (visible->second.mandatory == 0) { + visible->second.optionals.insert( + VisibleMember::Optionals::value_type(ifc->getScopedName(), *i)); + } + }} + {for (InheritedInterfaces::const_iterator i( + ifc->m_inheritedInterfaces.begin()); + i != ifc->m_inheritedInterfaces.end(); ++i) + { + if (!i->isOptional()) { + addOptionalVisibleMembers(i->getResolved()); + } + }} +} + +bool AstInterface::increment(sal_uInt16 * counter, char const * sort) const { + if (*counter == SAL_MAX_UINT16) { + fprintf( + stderr, "%s: interface %s has too many direct %s\n", + idlc()->getOptions()->getProgramName().getStr(), + getScopedName().getStr(), sort); + return false; + } + ++*counter; + return true; +} diff --git a/idlc/source/astoperation.cxx b/idlc/source/astoperation.cxx new file mode 100644 index 000000000000..5fff08ee7404 --- /dev/null +++ b/idlc/source/astoperation.cxx @@ -0,0 +1,153 @@ +/************************************************************************* + * + * 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_idlc.hxx" +#include <idlc/astoperation.hxx> +#include <idlc/asttype.hxx> +#include <idlc/astbasetype.hxx> +#include <idlc/astparameter.hxx> +#include <idlc/errorhandler.hxx> + +#include "registry/writer.hxx" + +using namespace ::rtl; + +void AstOperation::setExceptions(DeclList const * pExceptions) +{ + if (pExceptions != 0) { + if (isOneway()) { + idlc()->error()->error1(EIDL_ONEWAY_RAISE_CONFLICT, this); + } + m_exceptions = *pExceptions; + } +} + +bool AstOperation::isVariadic() const { + DeclList::const_iterator i(getIteratorEnd()); + return i != getIteratorBegin() + && static_cast< AstParameter const * >(*(--i))->isRest(); +} + +sal_Bool AstOperation::dumpBlob(typereg::Writer & rBlob, sal_uInt16 index) +{ + sal_uInt16 nParam = getNodeCount(NT_parameter); + sal_uInt16 nExcep = nExceptions(); + RTMethodMode methodMode = RT_MODE_TWOWAY; + + if ( isOneway() ) + methodMode = RT_MODE_ONEWAY; + + rtl::OUString returnTypeName; + if (m_pReturnType == 0) { + returnTypeName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("void")); + } else { + returnTypeName = rtl::OStringToOUString( + m_pReturnType->getRelativName(), RTL_TEXTENCODING_UTF8); + } + rBlob.setMethodData( + index, getDocumentation(), methodMode, + OStringToOUString(getLocalName(), RTL_TEXTENCODING_UTF8), + returnTypeName, nParam, nExcep); + + if ( nParam ) + { + DeclList::const_iterator iter = getIteratorBegin(); + DeclList::const_iterator end = getIteratorEnd(); + AstDeclaration* pDecl = NULL; + RTParamMode paramMode; + sal_uInt16 paramIndex = 0; + while ( iter != end ) + { + pDecl = *iter; + if ( pDecl->getNodeType() == NT_parameter ) + { + AstParameter* pParam = (AstParameter*)pDecl; + switch (pParam->getDirection()) + { + case DIR_IN : + paramMode = RT_PARAM_IN; + break; + case DIR_OUT : + paramMode = RT_PARAM_OUT; + break; + case DIR_INOUT : + paramMode = RT_PARAM_INOUT; + break; + default: + paramMode = RT_PARAM_INVALID; + break; + } + if (pParam->isRest()) { + paramMode = static_cast< RTParamMode >( + paramMode | RT_PARAM_REST); + } + + rBlob.setMethodParameterData( + index, paramIndex++, paramMode, + OStringToOUString( + pDecl->getLocalName(), RTL_TEXTENCODING_UTF8), + OStringToOUString( + pParam->getType()->getRelativName(), + RTL_TEXTENCODING_UTF8)); + } + ++iter; + } + } + + if ( nExcep ) + { + DeclList::iterator iter = m_exceptions.begin(); + DeclList::iterator end = m_exceptions.end(); + sal_uInt16 exceptIndex = 0; + while ( iter != end ) + { + rBlob.setMethodExceptionTypeName( + index, exceptIndex++, + OStringToOUString( + (*iter)->getRelativName(), RTL_TEXTENCODING_UTF8)); + ++iter; + } + } + + return sal_True; +} + +AstDeclaration* AstOperation::addDeclaration(AstDeclaration* pDecl) +{ + if ( pDecl->getNodeType() == NT_parameter ) + { + AstParameter* pParam = (AstParameter*)pDecl; + if ( isOneway() && + (pParam->getDirection() == DIR_OUT || pParam->getDirection() == DIR_INOUT) ) + { + idlc()->error()->error2(EIDL_ONEWAY_CONFLICT, pDecl, this); + return NULL; + } + } + return AstScope::addDeclaration(pDecl); +} diff --git a/idlc/source/astscope.cxx b/idlc/source/astscope.cxx new file mode 100644 index 000000000000..4d1e182320e0 --- /dev/null +++ b/idlc/source/astscope.cxx @@ -0,0 +1,356 @@ +/************************************************************************* + * + * 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_idlc.hxx" +#include <idlc/astscope.hxx> +#include <idlc/astbasetype.hxx> +#ifndef _IDLC_ASTINERFACE_HXX_ +#include <idlc/astinterface.hxx> +#endif +#include <idlc/errorhandler.hxx> + + +using namespace ::rtl; + +sal_Bool isGlobal(const OString& scopedName) +{ + if ((scopedName.getLength() == 0) || (scopedName.indexOf(':') == 0)) + { + return sal_True; + } + return sal_False; +} + +AstScope::AstScope(NodeType nodeType) + : m_nodeType(nodeType) +{ + +} + +AstScope::~AstScope() +{ + +} + +AstDeclaration* AstScope::addDeclaration(AstDeclaration* pDecl) +{ + AstDeclaration* pDeclaration = NULL; + + if ((pDeclaration = lookupForAdd(pDecl)) != NULL) + { + if (pDecl->getNodeType() == NT_union_branch ) + { + m_declarations.push_back(pDecl); + return pDecl; + } + if ( pDecl->hasAncestor(pDeclaration) ) + { + idlc()->error()->error2(EIDL_REDEF_SCOPE, pDecl, pDeclaration); + return NULL; + } + if ( (pDecl->getNodeType() == pDeclaration->getNodeType()) && + (pDecl->getNodeType() == NT_sequence + || pDecl->getNodeType() == NT_array + || pDecl->getNodeType() == NT_instantiated_struct) ) + { + return pDeclaration; + } + if ( (pDeclaration->getNodeType() == NT_interface) + && (pDecl->getNodeType() == NT_interface) + && !((AstInterface*)pDeclaration)->isDefined() ) + { + m_declarations.push_back(pDecl); + return pDecl; + } + if ( (NT_service == m_nodeType) && + ( ((pDecl->getNodeType() == NT_interface_member) + && (pDeclaration->getNodeType() == NT_interface)) || + ((pDecl->getNodeType() == NT_service_member) + && (pDeclaration->getNodeType() == NT_service)) ) + ) + { + m_declarations.push_back(pDecl); + return pDecl; + } + + idlc()->error()->error2(EIDL_REDEF_SCOPE, scopeAsDecl(this), pDecl); + return NULL; + } + + m_declarations.push_back(pDecl); + return pDecl; +} + +sal_uInt16 AstScope::getNodeCount(NodeType nodeType) +{ + DeclList::const_iterator iter = getIteratorBegin(); + DeclList::const_iterator end = getIteratorEnd(); + AstDeclaration* pDecl = NULL; + sal_uInt16 count = 0; + + while ( iter != end ) + { + pDecl = *iter; + if ( pDecl->getNodeType() == nodeType ) + count++; + ++iter; + } + return count; +} + +AstDeclaration* AstScope::lookupByName(const OString& scopedName) +{ + AstDeclaration* pDecl = NULL; + AstScope* pScope = NULL; + if (scopedName.getLength() == 0) + return NULL; + + // If name starts with "::" start look up in global scope + if ( isGlobal(scopedName) ) + { + pDecl = scopeAsDecl(this); + if ( !pDecl ) + return NULL; + + pScope = pDecl->getScope(); + // If this is the global scope ... + if ( !pScope ) + { + // look up the scopedName part after "::" + OString subName = scopedName.copy(2); + pDecl = lookupByName(subName); + return pDecl; + //return pScope->lookupByName(); + } + // OK, not global scope yet, so simply iterate with parent scope + pDecl = pScope->lookupByName(scopedName); + return pDecl; + } + + // The name does not start with "::" + // Look up in the local scope and start with the first scope + sal_Int32 nIndex = scopedName.indexOf(':'); + OString firstScope = nIndex > 0 ? scopedName.copy(0, nIndex) : scopedName; + sal_Bool bFindFirstScope = sal_True; + pDecl = lookupByNameLocal(firstScope); + if ( !pDecl ) + { + bFindFirstScope = sal_False; + + // OK, not found. Go down parent scope chain + pDecl = scopeAsDecl(this); + if ( pDecl ) + { + pScope = pDecl->getScope(); + if ( pScope ) + pDecl = pScope->lookupByName(scopedName); + else + pDecl = NULL; + + // Special case for scope which is an interface. We + // have to look in the inherited interfaces as well. + if ( !pDecl ) + { + if (m_nodeType == NT_interface) + pDecl = lookupInInherited(scopedName); + } + } + } + + if ( bFindFirstScope && (firstScope != scopedName) ) + { + sal_Int32 i = 0; + sal_Int32 nOffset = 2; + do + { + pScope = declAsScope(pDecl); + if( pScope ) + { + pDecl = pScope->lookupByNameLocal(scopedName.getToken(nOffset, ':', i )); + nOffset = 1; + } + if( !pDecl ) + break; + } while( i != -1 ); + + if ( !pDecl ) + { + // last try if is not the global scope and the scopeName isn't specify global too + pDecl = scopeAsDecl(this); + if ( pDecl && (pDecl->getLocalName() != "") ) + { + pScope = pDecl->getScope(); + if ( pScope ) + pDecl = pScope->lookupByName(scopedName); + } else + { + pDecl = NULL; + } + } + + } + + return pDecl; +} + +AstDeclaration* AstScope::lookupByNameLocal(const OString& name) const +{ + DeclList::const_iterator iter(m_declarations.begin()); + DeclList::const_iterator end(m_declarations.end()); + AstDeclaration* pDecl = NULL; + + while ( iter != end ) + { + pDecl = *iter; + if ( pDecl->getLocalName() == name ) + return pDecl; + ++iter; + } + return NULL; +} + +AstDeclaration* AstScope::lookupInInherited(const OString& scopedName) const +{ + AstInterface* pInterface = (AstInterface*)this; + + if ( !pInterface ) + return NULL; + + // Can't look in an interface which was not yet defined + if ( !pInterface->getScope() ) + { + idlc()->error()->forwardLookupError(pInterface, scopedName); + } + + // OK, loop through inherited interfaces. Stop when you find it + AstInterface::InheritedInterfaces::const_iterator iter( + pInterface->getAllInheritedInterfaces().begin()); + AstInterface::InheritedInterfaces::const_iterator end( + pInterface->getAllInheritedInterfaces().end()); + while ( iter != end ) + { + AstInterface const * resolved = iter->getResolved(); + AstDeclaration* pDecl = resolved->lookupByNameLocal(scopedName); + if ( pDecl ) + return pDecl; + pDecl = resolved->lookupInInherited(scopedName); + if ( pDecl ) + return pDecl; + ++iter; + } + // Not found + return NULL; +} + +AstDeclaration* AstScope::lookupPrimitiveType(ExprType type) +{ + AstDeclaration* pDecl = NULL; + AstScope* pScope = NULL; + AstBaseType* pBaseType = NULL; + OString typeName; + pDecl = scopeAsDecl(this); + if ( !pDecl ) + return NULL; + pScope = pDecl->getScope(); + if ( pScope) + return pScope->lookupPrimitiveType(type); + + switch (type) + { + case ET_none: + OSL_ASSERT(false); + break; + case ET_short: + typeName = OString("short"); + break; + case ET_ushort: + typeName = OString("unsigned short"); + break; + case ET_long: + typeName = OString("long"); + break; + case ET_ulong: + typeName = OString("unsigned long"); + break; + case ET_hyper: + typeName = OString("hyper"); + break; + case ET_uhyper: + typeName = OString("unsigned hyper"); + break; + case ET_float: + typeName = OString("float"); + break; + case ET_double: + typeName = OString("double"); + break; + case ET_char: + typeName = OString("char"); + break; + case ET_byte: + typeName = OString("byte"); + break; + case ET_boolean: + typeName = OString("boolean"); + break; + case ET_any: + typeName = OString("any"); + break; + case ET_void: + typeName = OString("void"); + break; + case ET_type: + typeName = OString("type"); + break; + case ET_string: + typeName = OString("string"); + break; + } + + pDecl = lookupByNameLocal(typeName); + + if ( pDecl && (pDecl->getNodeType() == NT_predefined) ) + { + pBaseType = (AstBaseType*)pDecl; + + if ( pBaseType->getExprType() == type ) + return pDecl; + } + + return NULL; +} + +AstDeclaration* AstScope::lookupForAdd(AstDeclaration* pDecl) +{ + if ( !pDecl ) + return NULL; + + AstDeclaration* pRetDecl = lookupByNameLocal(pDecl->getLocalName()); + + return pRetDecl; +} diff --git a/idlc/source/astservice.cxx b/idlc/source/astservice.cxx new file mode 100644 index 000000000000..11f638cc0f66 --- /dev/null +++ b/idlc/source/astservice.cxx @@ -0,0 +1,70 @@ +/************************************************************************* + * + * 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_idlc.hxx" + +#include "sal/config.h" + +#include "idlc/astmember.hxx" +#include "idlc/astoperation.hxx" +#include "idlc/astservice.hxx" +#include "idlc/asttype.hxx" + +bool AstService::checkLastConstructor() const { + AstOperation const * last = static_cast< AstOperation const * >(getLast()); + for (DeclList::const_iterator i(getIteratorBegin()); i != getIteratorEnd(); + ++i) + { + if (*i != last && (*i)->getNodeType() == NT_operation) { + AstOperation const * ctor = static_cast< AstOperation * >(*i); + if (ctor->isVariadic() && last->isVariadic()) { + return true; + } + sal_uInt32 n = ctor->nMembers(); + if (n == last->nMembers()) { + for (DeclList::const_iterator i1(ctor->getIteratorBegin()), + i2(last->getIteratorBegin()); + i1 != ctor->getIteratorEnd(); ++i1, ++i2) + { + sal_Int32 r1; + AstDeclaration const * t1 = deconstructAndResolveTypedefs( + static_cast< AstMember * >(*i1)->getType(), &r1); + sal_Int32 r2; + AstDeclaration const * t2 = deconstructAndResolveTypedefs( + static_cast< AstMember * >(*i2)->getType(), &r2); + if (r1 != r2 || t1->getScopedName() != t2->getScopedName()) + { + return false; + } + } + return true; + } + } + } + return false; +} diff --git a/idlc/source/aststack.cxx b/idlc/source/aststack.cxx new file mode 100644 index 000000000000..9697727ac861 --- /dev/null +++ b/idlc/source/aststack.cxx @@ -0,0 +1,137 @@ +/************************************************************************* + * + * 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_idlc.hxx" +#include <rtl/alloc.h> +#include <idlc/aststack.hxx> +#include <idlc/astscope.hxx> + +#define STACKSIZE_INCREMENT 64 + +AstStack::AstStack() + : m_stack((AstScope**)rtl_allocateZeroMemory(sizeof(AstScope*) * STACKSIZE_INCREMENT)) + , m_size(STACKSIZE_INCREMENT) + , m_top(0) +{ +} + +AstStack::~AstStack() +{ + for(sal_uInt32 i=0; i < m_top; i++) + { + if (m_stack[i]) + delete(m_stack[i]); + } + + rtl_freeMemory(m_stack); +} + +sal_uInt32 AstStack::depth() +{ + return m_top; +} + +AstScope* AstStack::top() +{ + if (m_top < 1) + return NULL; + return m_stack[m_top - 1]; +} + +AstScope* AstStack::bottom() +{ + if (m_top == 0) + return NULL; + return m_stack[0]; +} + +AstScope* AstStack::nextToTop() +{ + AstScope *tmp, *retval; + + if (depth() < 2) + return NULL; + + tmp = top(); // Save top + (void) pop(); // Pop it + retval = top(); // Get next one down + (void) push(tmp); // Push top back + return retval; // Return next one down +} + +AstScope* AstStack::topNonNull() +{ + for (sal_uInt32 i = m_top; i > 0; i--) + { + if ( m_stack[i - 1] ) + return m_stack[i - 1]; + } + return NULL; +} + +AstStack* AstStack::push(AstScope* pScope) +{ + AstScope **tmp; +// AstDeclaration *pDecl = ScopeAsDecl(pScope); + sal_uInt32 newSize; + sal_uInt32 i; + + // Make sure there's space for one more + if (m_size == m_top) + { + newSize = m_size; + newSize += STACKSIZE_INCREMENT; + tmp = (AstScope**)rtl_allocateZeroMemory(sizeof(AstScope*) * newSize); + + for(i=0; i < m_size; i++) + tmp[i] = m_stack[i]; + + rtl_freeMemory(m_stack); + m_stack = tmp; + } + + // Insert new scope + m_stack[m_top++] = pScope; + + return this; +} + +void AstStack::pop() +{ + AstScope *pScope; + + if (m_top < 1) + return; + pScope = m_stack[--m_top]; +} + +void AstStack::clear() +{ + m_top = 0; +} + diff --git a/idlc/source/aststruct.cxx b/idlc/source/aststruct.cxx new file mode 100644 index 000000000000..913ebaed42c4 --- /dev/null +++ b/idlc/source/aststruct.cxx @@ -0,0 +1,191 @@ +/************************************************************************* + * + * 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_idlc.hxx" +#include <idlc/aststruct.hxx> +#ifndef _IDLC_ASTMember_HXX_ +#include <idlc/astmember.hxx> +#endif + +#include "registry/version.h" +#include "registry/writer.hxx" + +using namespace ::rtl; + +AstStruct::AstStruct( + const OString& name, std::vector< rtl::OString > const & typeParameters, + AstStruct* pBaseType, AstScope* pScope) + : AstType(NT_struct, name, pScope) + , AstScope(NT_struct) + , m_pBaseType(pBaseType) +{ + for (std::vector< rtl::OString >::const_iterator i(typeParameters.begin()); + i != typeParameters.end(); ++i) + { + m_typeParameters.push_back( + new AstDeclaration(NT_type_parameter, *i, 0)); + } +} + +AstStruct::AstStruct(const NodeType type, + const OString& name, + AstStruct* pBaseType, + AstScope* pScope) + : AstType(type, name, pScope) + , AstScope(type) + , m_pBaseType(pBaseType) +{ +} + +AstStruct::~AstStruct() +{ + for (DeclList::iterator i(m_typeParameters.begin()); + i != m_typeParameters.end(); ++i) + { + delete *i; + } +} + +AstDeclaration const * AstStruct::findTypeParameter(rtl::OString const & name) + const +{ + for (DeclList::const_iterator i(m_typeParameters.begin()); + i != m_typeParameters.end(); ++i) + { + if ((*i)->getLocalName() == name) { + return *i; + } + } + return 0; +} + +bool AstStruct::isType() const { + return getNodeType() == NT_struct + ? getTypeParameterCount() == 0 : AstDeclaration::isType(); +} + +sal_Bool AstStruct::dump(RegistryKey& rKey) +{ + RegistryKey localKey; + if (rKey.createKey( OStringToOUString(getFullName(), RTL_TEXTENCODING_UTF8 ), localKey)) + { + fprintf(stderr, "%s: warning, could not create key '%s' in '%s'\n", + idlc()->getOptions()->getProgramName().getStr(), + getFullName().getStr(), OUStringToOString(rKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr()); + return sal_False; + } + + if (m_typeParameters.size() > SAL_MAX_UINT16) { + fprintf( + stderr, + ("%s: polymorphic struct type template %s has too many type" + " parameters\n"), + idlc()->getOptions()->getProgramName().getStr(), + getScopedName().getStr()); + return false; + } + + sal_uInt16 nMember = getNodeCount(NT_member); + + RTTypeClass typeClass = RT_TYPE_STRUCT; + if ( getNodeType() == NT_exception ) + typeClass = RT_TYPE_EXCEPTION; + + OUString emptyStr; + typereg::Writer aBlob( + (m_typeParameters.empty() && !m_bPublished + ? TYPEREG_VERSION_0 : TYPEREG_VERSION_1), + getDocumentation(), emptyStr, typeClass, m_bPublished, + OStringToOUString(getRelativName(), RTL_TEXTENCODING_UTF8), + m_pBaseType == 0 ? 0 : 1, nMember, 0, + static_cast< sal_uInt16 >(m_typeParameters.size())); + if (m_pBaseType != 0) { + aBlob.setSuperTypeName( + 0, + OStringToOUString( + m_pBaseType->getRelativName(), RTL_TEXTENCODING_UTF8)); + } + + if ( nMember > 0 ) + { + DeclList::const_iterator iter = getIteratorBegin(); + DeclList::const_iterator end = getIteratorEnd(); + AstDeclaration* pDecl = NULL; + AstMember* pMember = NULL; + OUString docu; + sal_uInt16 index = 0; + while ( iter != end ) + { + pDecl = *iter; + if ( pDecl->getNodeType() == NT_member ) + { + pMember = (AstMember*)pDecl; + RTFieldAccess flags = RT_ACCESS_READWRITE; + rtl::OString typeName; + if (pMember->getType()->getNodeType() == NT_type_parameter) { + flags |= RT_ACCESS_PARAMETERIZED_TYPE; + typeName = pMember->getType()->getLocalName(); + } else { + typeName = pMember->getType()->getRelativName(); + } + aBlob.setFieldData( + index++, pMember->getDocumentation(), emptyStr, flags, + OStringToOUString( + pMember->getLocalName(), RTL_TEXTENCODING_UTF8), + OStringToOUString(typeName, RTL_TEXTENCODING_UTF8), + RTConstValue()); + } + ++iter; + } + } + + sal_uInt16 index = 0; + for (DeclList::iterator i(m_typeParameters.begin()); + i != m_typeParameters.end(); ++i) + { + aBlob.setReferenceData( + index++, emptyStr, RT_REF_TYPE_PARAMETER, RT_ACCESS_INVALID, + OStringToOUString( + (*i)->getLocalName(), RTL_TEXTENCODING_UTF8)); + } + + sal_uInt32 aBlobSize; + void const * pBlob = aBlob.getBlob(&aBlobSize); + + if (localKey.setValue(emptyStr, RG_VALUETYPE_BINARY, + (RegValue)pBlob, aBlobSize)) + { + fprintf(stderr, "%s: warning, could not set value of key \"%s\" in %s\n", + idlc()->getOptions()->getProgramName().getStr(), + getFullName().getStr(), OUStringToOString(localKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr()); + return sal_False; + } + + return sal_True; +} + diff --git a/idlc/source/aststructinstance.cxx b/idlc/source/aststructinstance.cxx new file mode 100644 index 000000000000..457c48ad00a7 --- /dev/null +++ b/idlc/source/aststructinstance.cxx @@ -0,0 +1,70 @@ +/************************************************************************* + * + * 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_idlc.hxx" + +#include "idlc/aststructinstance.hxx" + +#include "idlc/asttype.hxx" +#include "idlc/idlctypes.hxx" + +#include "rtl/strbuf.hxx" +#include "rtl/string.hxx" + +namespace { + +rtl::OString createName( + AstType const * typeTemplate, DeclList const * typeArguments) +{ + rtl::OStringBuffer buf(typeTemplate->getScopedName()); + if (typeArguments != 0) { + buf.append('<'); + for (DeclList::const_iterator i(typeArguments->begin()); + i != typeArguments->end(); ++i) + { + if (i != typeArguments->begin()) { + buf.append(','); + } + if (*i != 0) { + buf.append((*i)->getScopedName()); + } + } + buf.append('>'); + } + return buf.makeStringAndClear(); +} + +} + +AstStructInstance::AstStructInstance( + AstType const * typeTemplate, DeclList const * typeArguments, + AstScope * scope): + AstType( + NT_instantiated_struct, createName(typeTemplate, typeArguments), scope), + m_typeTemplate(typeTemplate), m_typeArguments(*typeArguments) +{} diff --git a/idlc/source/astunion.cxx b/idlc/source/astunion.cxx new file mode 100644 index 000000000000..f4b1ede57bd4 --- /dev/null +++ b/idlc/source/astunion.cxx @@ -0,0 +1,401 @@ +/************************************************************************* + * + * 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_idlc.hxx" +#include <idlc/astunion.hxx> +#include <idlc/astbasetype.hxx> +#include <idlc/errorhandler.hxx> + +#include "registry/version.h" +#include "registry/writer.hxx" + +using namespace ::rtl; + +AstUnion::AstUnion(const ::rtl::OString& name, AstType* pDiscType, AstScope* pScope) + : AstStruct(NT_union, name, NULL, pScope) + , m_pDiscriminantType(pDiscType) + , m_discExprType(ET_long) +{ + AstBaseType* pBaseType; + + if ( !pDiscType ) + { + m_pDiscriminantType = NULL; + m_discExprType = ET_none; + return; + } + /* + * If the discriminator type is a predefined type + * then install the equivalent coercion target type in + * the pd_udisc_type field. + */ + if ( pDiscType->getNodeType() == NT_predefined ) + { + pBaseType = (AstBaseType*)pDiscType; + if ( !pBaseType ) + { + m_pDiscriminantType = NULL; + m_discExprType = ET_none; + return; + } + m_pDiscriminantType = pDiscType; + switch (pBaseType->getExprType()) + { + case ET_long: + case ET_ulong: + case ET_short: + case ET_ushort: + case ET_char: + case ET_boolean: + m_discExprType = pBaseType->getExprType(); + break; + default: + m_discExprType = ET_none; + m_pDiscriminantType = NULL; + break; + } + } else + if (pDiscType->getNodeType() == NT_enum) + { + m_discExprType = ET_any; + m_pDiscriminantType = pDiscType; + } else + { + m_discExprType = ET_none; + m_pDiscriminantType = NULL; + } + + if ( !m_pDiscriminantType ) + idlc()->error()->error2(EIDL_DISC_TYPE, this, pDiscType); +} + +AstUnion::~AstUnion() +{ +} + +AstDeclaration* AstUnion::addDeclaration(AstDeclaration* pDecl) +{ + if ( pDecl->getNodeType() == NT_union_branch ) + { + AstUnionBranch* pBranch = (AstUnionBranch*)pDecl; + if ( lookupBranch(pBranch) ) + { + idlc()->error()->error2(EIDL_MULTIPLE_BRANCH, this, pDecl); + return NULL; + } + } + + return AstScope::addDeclaration(pDecl); +} + +AstUnionBranch* AstUnion::lookupBranch(AstUnionBranch* pBranch) +{ + AstUnionLabel* pLabel = NULL; + + if ( pBranch ) + pLabel = pBranch->getLabel(); + + if ( pLabel ) + { + if (pLabel->getLabelKind() == UL_default) + return lookupDefault(); + if (m_discExprType == ET_any) + /* CONVENTION: indicates enum discr */ + return lookupEnum(pBranch); + return lookupLabel(pBranch); + } + return NULL; +} + +AstUnionBranch* AstUnion::lookupDefault(sal_Bool bReportError) +{ + DeclList::const_iterator iter = getIteratorBegin(); + DeclList::const_iterator end = getIteratorEnd(); + AstUnionBranch *pBranch = NULL; + AstDeclaration *pDecl = NULL; + + while ( iter != end ) + { + pDecl = *iter; + if ( pDecl->getNodeType() == NT_union_branch ) + { + pBranch = (AstUnionBranch*)pDecl; + if (pBranch == NULL) + { + ++iter; + continue; + } + if ( pBranch->getLabel() != NULL && + pBranch->getLabel()->getLabelKind() == UL_default) + { + if ( bReportError ) + idlc()->error()->error2(EIDL_MULTIPLE_BRANCH, this, pBranch); + return pBranch; + } + } + ++iter; + } + return NULL; +} + +AstUnionBranch* AstUnion::lookupLabel(AstUnionBranch* pBranch) +{ + AstUnionLabel* pLabel = pBranch->getLabel(); + + if ( !pLabel->getLabelValue() ) + return pBranch; +// pLabel->getLabelValue()->setExprValue(pLabel->getLabelValue()->coerce(m_discExprType, sal_False)); + AstExprValue* pLabelValue = pLabel->getLabelValue()->coerce( + m_discExprType, sal_False); + if ( !pLabelValue ) + { + idlc()->error()->evalError(pLabel->getLabelValue()); + return pBranch; + } else + { + pLabel->getLabelValue()->setExprValue(pLabelValue); + } + + DeclList::const_iterator iter = getIteratorBegin(); + DeclList::const_iterator end = getIteratorEnd(); + AstUnionBranch* pB = NULL; + AstDeclaration* pDecl = NULL; + + while ( iter != end ) + { + pDecl = *iter; + if ( pDecl->getNodeType() == NT_union_branch ) + { + pB = (AstUnionBranch*)pDecl; + if ( !pB ) + { + ++iter; + continue; + } + if ( pB->getLabel() != NULL && + pB->getLabel()->getLabelKind() == UL_label && + pB->getLabel()->getLabelValue()->compare(pLabel->getLabelValue()) ) + { + idlc()->error()->error2(EIDL_MULTIPLE_BRANCH, this, pBranch); + return pBranch; + } + } + ++iter; + } + return NULL; +} + +AstUnionBranch* AstUnion::lookupEnum(AstUnionBranch* pBranch) +{ + AstDeclaration const * pType = resolveTypedefs(m_pDiscriminantType); + if ( pType->getNodeType() != NT_enum ) + return NULL; + + AstUnionLabel* pLabel = pBranch->getLabel(); + AstExpression* pExpr = pLabel->getLabelValue(); + if ( !pExpr ) + return pBranch; + + /* + * Expecting a symbol label + */ + if ( pExpr->getCombOperator() != EC_symbol) + { + idlc()->error()->enumValExpected(this); + return pBranch; + } + + /* + * See if the symbol defines a constant in the discriminator enum + */ + AstEnum* pEnum = (AstEnum*)pType; + AstDeclaration* pDecl = pEnum->lookupByName(*pExpr->getSymbolicName()); + if ( pDecl == NULL || pDecl->getScope() != pEnum) + { + idlc()->error()->enumValLookupFailure(this, pEnum, *pExpr->getSymbolicName()); + return pBranch; + } + + + DeclList::const_iterator iter = getIteratorBegin(); + DeclList::const_iterator end = getIteratorEnd(); + AstUnionBranch* pB = NULL; + pDecl = NULL; + + while ( iter != end ) + { + pDecl = *iter; + if ( pDecl->getNodeType() == NT_union_branch ) + { + pB = (AstUnionBranch*)pDecl; + if ( !pB ) + { + ++iter; + continue; + } + if ( pB->getLabel() != NULL && + pB->getLabel()->getLabelKind() == UL_label && + pB->getLabel()->getLabelValue()->compare(pLabel->getLabelValue()) ) + { + idlc()->error()->error2(EIDL_MULTIPLE_BRANCH, this, pBranch); + return pBranch; + } + } + ++iter; + } + return NULL; +} + +sal_Bool AstUnion::dump(RegistryKey& rKey) +{ + RegistryKey localKey; + if (rKey.createKey( OStringToOUString(getFullName(), RTL_TEXTENCODING_UTF8 ), localKey)) + { + fprintf(stderr, "%s: warning, could not create key '%s' in '%s'\n", + idlc()->getOptions()->getProgramName().getStr(), + getFullName().getStr(), OUStringToOString(rKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr()); + return sal_False; + } + + sal_uInt16 nMember = getNodeCount(NT_union_branch); + + OUString emptyStr; + typereg::Writer aBlob( + TYPEREG_VERSION_0, getDocumentation(), emptyStr, RT_TYPE_UNION, + false, OStringToOUString(getRelativName(), RTL_TEXTENCODING_UTF8), 1, + nMember, 0, 0); + aBlob.setSuperTypeName( + 0, + OStringToOUString( + getDiscrimantType()->getScopedName(), RTL_TEXTENCODING_UTF8)); + + if ( nMember > 0 ) + { + DeclList::const_iterator iter = getIteratorBegin(); + DeclList::const_iterator end = getIteratorEnd(); + AstDeclaration* pDecl = NULL; + AstUnionBranch* pBranch = NULL; + AstUnionBranch* pDefault = lookupDefault(sal_False); + AstUnionLabel* pLabel = NULL; + AstExprValue* pExprValue = NULL; + RTConstValue aConst; + RTFieldAccess access = RT_ACCESS_READWRITE; + OUString docu; + sal_uInt16 index = 0; + if ( pDefault ) + index = 1; + + sal_Int64 disc = 0; + while ( iter != end ) + { + pDecl = *iter; + if ( pDecl->getNodeType() == NT_union_branch ) + { + pBranch = (AstUnionBranch*)pDecl; + if (pBranch == pDefault) + { + ++iter; + continue; + } + + pLabel = pBranch->getLabel(); + pExprValue = pLabel->getLabelValue()->coerce(ET_hyper, sal_False); + aConst.m_type = RT_TYPE_INT64; + aConst.m_value.aHyper = pExprValue->u.hval; + if ( aConst.m_value.aHyper > disc ) + disc = aConst.m_value.aHyper; + + aBlob.setFieldData( + index++, pBranch->getDocumentation(), emptyStr, RT_ACCESS_READWRITE, + OStringToOUString( + pBranch->getLocalName(), RTL_TEXTENCODING_UTF8), + OStringToOUString( + pBranch->getType()->getRelativName(), + RTL_TEXTENCODING_UTF8), + aConst); + } + ++iter; + } + + if ( pDefault ) + { + access = RT_ACCESS_DEFAULT; + aConst.m_type = RT_TYPE_INT64; + aConst.m_value.aHyper = disc + 1; + aBlob.setFieldData( + 0, pDefault->getDocumentation(), emptyStr, RT_ACCESS_DEFAULT, + OStringToOUString( + pDefault->getLocalName(), RTL_TEXTENCODING_UTF8), + OStringToOUString( + pDefault->getType()->getRelativName(), + RTL_TEXTENCODING_UTF8), + aConst); + } + } + + sal_uInt32 aBlobSize; + void const * pBlob = aBlob.getBlob(&aBlobSize); + + if (localKey.setValue(OUString(), RG_VALUETYPE_BINARY, + (RegValue)pBlob, aBlobSize)) + { + fprintf(stderr, "%s: warning, could not set value of key \"%s\" in %s\n", + idlc()->getOptions()->getProgramName().getStr(), + getFullName().getStr(), OUStringToOString(localKey.getRegistryName(), RTL_TEXTENCODING_UTF8).getStr()); + return sal_False; + } + + return sal_True; +} + +AstUnionBranch::AstUnionBranch(AstUnionLabel* pLabel, AstType const * pType, const ::rtl::OString& name, AstScope* pScope) + : AstMember(NT_union_branch, pType, name, pScope) + , m_pLabel(pLabel) +{ +} + +AstUnionBranch::~AstUnionBranch() +{ + if ( m_pLabel ) + delete m_pLabel; +} + +AstUnionLabel::AstUnionLabel(UnionLabel labelKind, AstExpression* pExpr) + : m_label(labelKind) + , m_pLabelValue(pExpr) +{ + if ( m_pLabelValue ) + m_pLabelValue->evaluate(EK_const); +} + +AstUnionLabel::~AstUnionLabel() +{ + if ( m_pLabelValue ) + delete m_pLabelValue; +} + diff --git a/idlc/source/attributeexceptions.hxx b/idlc/source/attributeexceptions.hxx new file mode 100644 index 000000000000..2981c09220f6 --- /dev/null +++ b/idlc/source/attributeexceptions.hxx @@ -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. + * + ************************************************************************/ + +#ifndef INCLUDED_idlc_source_attributeexceptions_hxx +#define INCLUDED_idlc_source_attributeexceptions_hxx + +#include "rtl/ustring.hxx" + +struct AttributeExceptions { + struct Part { + rtl::OUString const * documentation; + DeclList const * exceptions; + }; + Part get; + Part set; +}; + +#endif diff --git a/idlc/source/errorhandler.cxx b/idlc/source/errorhandler.cxx new file mode 100644 index 000000000000..4ab4844eeca7 --- /dev/null +++ b/idlc/source/errorhandler.cxx @@ -0,0 +1,695 @@ +/************************************************************************* + * + * 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_idlc.hxx" +#include <idlc/errorhandler.hxx> +#include <idlc/astinterface.hxx> + +using namespace ::rtl; + +static const sal_Char* errorCodeToMessage(ErrorCode eCode) +{ + switch (eCode) + { + case EIDL_NONE: + return "all is fine "; + case EIDL_SYNTAX_ERROR: + return ""; + case EIDL_REDEF: + return "illegal redefinition "; + case EIDL_REDEF_SCOPE: + return "illegal redefinition in scope "; + case EIDL_DEF_USE: + return "redefinition after use, "; + case EIDL_MULTIPLE_BRANCH: + return "union with duplicate branch label "; + case EIDL_COERCION_FAILURE: + return "coercion failure "; + case EIDL_SCOPE_CONFLICT: + return "definition scope is different than fwd declare scope, "; + case EIDL_ONEWAY_CONFLICT: + return "oneway operation with OUT|INOUT parameters or raises exceptions, "; + case EIDL_DISC_TYPE: + return "union with illegal discriminator type, "; + case EIDL_LABEL_TYPE: + return "label type incompatible with union discriminator type, "; + case EIDL_ILLEGAL_ADD: + return "illegal add operation, "; + case EIDL_ILLEGAL_USE: + return "illegal type used in expression, "; + case EIDL_ILLEGAL_RAISES: + return "non-exception type in raises(..) clause, "; + case EIDL_CANT_INHERIT: + return "cannot inherit "; + case EIDL_LOOKUP_ERROR: + return "error in lookup of symbol: "; + case EIDL_INHERIT_FWD_ERROR: + return ""; + case EIDL_CONSTANT_EXPECTED: + return "constant expected: "; + case EIDL_NAME_CASE_ERROR: + return "identifier used with two differing spellings: "; + case EIDL_ENUM_VAL_EXPECTED: + return "enumerator expected: "; + case EIDL_ENUM_VAL_NOT_FOUND: + return "enumerator by this name not defined: "; + case EIDL_EVAL_ERROR: + return "expression evaluation error: "; + case EIDL_AMBIGUOUS: + return "ambiguous definition: "; + case EIDL_DECL_NOT_DEFINED: + return "forward declared but never defined: "; + case EIDL_FWD_DECL_LOOKUP: + return ""; + case EIDL_RECURSIVE_TYPE: + return "illegal recursive use of type: "; + case EIDL_NONVOID_ONEWAY: + return "non-void return type in oneway operation: "; + case EIDL_NOT_A_TYPE: + return "specified symbol is not a type: "; + case EIDL_TYPE_NOT_VALID: + return "specified type is not valid in this context: "; + case EIDL_INTERFACEMEMBER_LOOKUP: + return "error in lookup of symbol, expected interface is not defined and no forward exists: "; + case EIDL_SERVICEMEMBER_LOOKUP: + return "error in lookup of symbol, expected service is not defined: "; + case EIDL_TYPE_IDENT_CONFLICT: + return "type and parameter/member name are equal: "; + case EIDL_ONEWAY_RAISE_CONFLICT: + return "oneway operation cannot raises exceptions: "; + case EIDL_WRONGATTRIBUTEFLAG: + return "the used flag is not valid in this context: "; + case EIDL_DEFINED_ATTRIBUTEFLAG: + return "flag is already set: "; + case EIDL_WRONGATTRIBUTEKEYWORD: + return "keyword not allowed: "; + case EIDL_MISSINGATTRIBUTEKEYWORD: + return "missing keyword: "; + case EIDL_BAD_ATTRIBUTE_FLAGS: + return + "the 'attribute' flag is mandatory, and only the 'bound' and" + " 'readonly' optional flags are accepted: "; + case EIDL_OPTIONALEXPECTED: + return "only the 'optional' flag is accepted: "; + case EIDL_MIXED_INHERITANCE: + return "interface inheritance declarations cannot appear in both an" + " interface's header and its body"; + case EIDL_DOUBLE_INHERITANCE: + return + "interface is (directly or indirectly) inherited more than once: "; + case EIDL_DOUBLE_MEMBER: + return + "member is (directly or indirectly) declared more than once: "; + case EIDL_CONSTRUCTOR_PARAMETER_NOT_IN: + return + "a service constructor parameter may not be an out or inout" + " parameter"; + case EIDL_CONSTRUCTOR_REST_PARAMETER_NOT_FIRST: + return + "no parameters may precede a rest parameter in a service" + " constructor"; + case EIDL_REST_PARAMETER_NOT_LAST: + return "no parameters may follow a rest parameter"; + case EIDL_REST_PARAMETER_NOT_ANY: + return "a rest parameter must be of type any"; + case EIDL_METHOD_HAS_REST_PARAMETER: + return "a rest parameter may not be used on an interface method"; + case EIDL_READONLY_ATTRIBUTE_SET_EXCEPTIONS: + return "a readonly attribute may not have a setter raises clause"; + case EIDL_UNSIGNED_TYPE_ARGUMENT: + return "an unsigned type cannot be used as a type argument"; + case EIDL_WRONG_NUMBER_OF_TYPE_ARGUMENTS: + return + "the number of given type arguments does not match the expected" + " number of type parameters"; + case EIDL_INSTANTIATED_STRUCT_TYPE_TYPEDEF: + return + "an instantiated polymorphic struct type cannot be used in a" + " typedef"; + case EIDL_IDENTICAL_TYPE_PARAMETERS: + return "two type parameters have the same name"; + case EIDL_STRUCT_TYPE_TEMPLATE_WITH_BASE: + return "a polymorphic struct type template may not have a base type"; + case EIDL_PUBLISHED_FORWARD: + return + "a published forward declaration of an interface type cannot be" + " followed by an unpublished declaration of that type"; + case EIDL_PUBLISHED_USES_UNPUBLISHED: + return + "an unpublished entity cannot be used in the declaration of a" + " published entity: "; + case EIDL_SIMILAR_CONSTRUCTORS: + return "two constructors have identical lists of parameter types"; + } + return "unknown errror"; +} + +static const sal_Char* warningCodeToMessage(WarningCode wCode) +{ + switch (wCode) + { + case WIDL_EXPID_CONFLICT: + return "exception id conflict: "; + case WIDL_REQID_CONFLICT: + return "request id conflict: "; + case WIDL_INHERIT_IDCONFLICT: + return "request id conflict in inheritance tree: "; + case WIDL_TYPE_IDENT_CONFLICT: + return "type and parameter|member name are equal: "; + case WIDL_WRONG_NAMING_CONV: + return "type or identifier doesn't fulfill the UNO naming convention: "; + } + return "unkown warning"; +} + +static const sal_Char* parseStateToMessage(ParseState state) +{ + switch (state) + { + case PS_NoState: + return "Statement can not be parsed"; + case PS_TypeDeclSeen: + return "Malformed type declaration"; + case PS_ConstantDeclSeen: + return "Malformed const declaration"; + case PS_ExceptionDeclSeen: + return "Malformed exception declaration"; + case PS_InterfaceDeclSeen: + return "Malformed interface declaration"; + case PS_ServiceDeclSeen: + return "Malformed servicve declaration"; + case PS_ModuleDeclSeen: + return "Malformed module declaration"; + case PS_AttributeDeclSeen: + return "Malformed attribute declaration"; + case PS_PropertyDeclSeen: + return "Malformed property declaration"; + case PS_OperationDeclSeen: + return "Malformed operation declaration"; + case PS_InterfaceInheritanceDeclSeen: + return "Malformed interface inheritance declaration"; + case PS_ConstantsDeclSeen: + return "Malformed constants declaration"; + case PS_ServiceSeen: + return "Missing service identifier following SERVICE keyword"; + case PS_ServiceIDSeen: + return "Missing '{' or illegal syntax following service identifier"; + case PS_ServiceSqSeen: + return "Illegal syntax following service '{' opener"; + case PS_ServiceBodySeen: + return "Illegal syntax following service '}' closer"; + case PS_ServiceMemberSeen: + return "Illegal syntax following service member declaration"; + case PS_ServiceIFHeadSeen: + return "Illegal syntax following header of an interface member"; + case PS_ServiceSHeadSeen: + return "Illegal syntax following header of an service member"; + case PS_ModuleSeen: + return "Missing module identifier following MODULE keyword"; + case PS_ModuleIDSeen: + return "Missing '{' or illegal syntax following module identifier"; + case PS_ModuleSqSeen: + return "Illegal syntax following module '{' opener"; + case PS_ModuleQsSeen: + return "Illegal syntax following module '}' closer"; + case PS_ModuleBodySeen: + return "Illegal syntax following module export(s)"; + case PS_ConstantsSeen: + return "Missing constants identifier following CONSTANTS keyword"; + case PS_ConstantsIDSeen: + return "Missing '{' or illegal syntax following constants identifier"; + case PS_ConstantsSqSeen: + return "Illegal syntax following module '{' opener"; + case PS_ConstantsQsSeen: + return "Illegal syntax following module '}' closer"; + case PS_ConstantsBodySeen: + return "Illegal syntax following constants export(s)"; + case PS_InterfaceSeen: + return "Missing interface identifier following INTERFACE keyword"; + case PS_InterfaceIDSeen: + return "Illegal syntax following interface identifier"; + case PS_InterfaceHeadSeen: + return "Illegal syntax following interface head"; + case PS_InheritSpecSeen: + return "Missing '{' or illegal syntax following inheritance spec"; + case PS_ForwardDeclSeen: + return "Missing ';' following forward interface declaration"; + case PS_InterfaceSqSeen: + return "Illegal syntax following interface '{' opener"; + case PS_InterfaceQsSeen: + return "Illegal syntax following interface '}' closer"; + case PS_InterfaceBodySeen: + return "Illegal syntax following interface export(s)"; + case PS_InheritColonSeen: + return "Illegal syntax following ':' starting inheritance list"; + case PS_SNListCommaSeen: + return "Found illegal scoped name in scoped name list"; + case PS_ScopedNameSeen: + return "Missing ',' following scoped name in scoped name list"; + case PS_SN_IDSeen: + return "Illegal component in scoped name"; + case PS_ScopeDelimSeen: + return "Illegal component in scoped name following '::'"; + case PS_ConstSeen: + return "Missing type or illegal syntax following CONST keyword"; + case PS_ConstTypeSeen: + return "Missing identifier or illegal syntax following const type"; + case PS_ConstIDSeen: + return "Missing '=' or illegal syntax after const identifier"; + case PS_ConstAssignSeen: + return "Missing value expr or illegal syntax following '='"; + case PS_ConstExprSeen: + return "Missing ';' or illegal syntax following value expr in const"; + case PS_TypedefSeen: + return "Missing type or illegal syntax following TYPEDEF keyword"; + case PS_TypeSpecSeen: + return "Missing declarators or illegal syntax following type spec"; + case PS_DeclaratorsSeen: + return "Illegal syntax following declarators in TYPEDEF declaration"; + case PS_StructSeen: + return "Missing struct identifier following STRUCT keyword"; + case PS_StructHeaderSeen: + return "Missing '{' or illegal syntax following struct inheritance spec"; + case PS_StructIDSeen: + return "Missing '{' or illegal syntax following struct identifier"; + case PS_StructSqSeen: + return "Illegal syntax following struct '{' opener"; + case PS_StructQsSeen: + return "Illegal syntax following struct '}' closer"; + case PS_StructBodySeen: + return "Illegal syntax following struct member(s)"; + case PS_MemberTypeSeen: + return "Illegal syntax or missing identifier following member type"; + case PS_MemberDeclsSeen: + return "Illegal syntax following member declarator(s)"; + case PS_MemberDeclsCompleted: + return "Missing ',' between member decls of same type(?)"; + case PS_UnionSeen: + return "Missing identifier following UNION keyword"; + case PS_UnionIDSeen: + return "Illegal syntax following union identifier"; + case PS_SwitchSeen: + return "Illegal syntax following SWITCH keyword"; + case PS_SwitchOpenParSeen: + return "Illegal syntax following '(' in switch in union"; + case PS_SwitchTypeSeen: + return "Illegal syntax following type decl in switch in union"; + case PS_SwitchCloseParSeen: + return "Missing union '{' opener"; + case PS_UnionSqSeen: + return "Illegal syntax following union '{' opener"; + case PS_UnionQsSeen: + return "Illegal syntax following union '}' closer"; + case PS_DefaultSeen: + return "Illegal syntax or missing ':' following DEFAULT keyword"; + case PS_UnionLabelSeen: + return "Illegal syntax following branch label in union"; + case PS_LabelColonSeen: + return "Illegal syntax following ':' in branch label in union"; + case PS_LabelExprSeen: + return "Illegal syntax following label expression in union"; + case PS_UnionElemSeen: + case PS_UnionElemCompleted: + return "Illegal syntax following union element"; + case PS_CaseSeen: + return "Illegal syntax following CASE keyword in union"; + case PS_UnionElemTypeSeen: + return "Illegal syntax following type decl in union element"; + case PS_UnionElemDeclSeen: + return "Illegal syntax following declarator in union element"; + case PS_UnionBodySeen: + return "Illegal syntax following union body statement(s)"; + case PS_EnumSeen: + return "Illegal syntax or missing identifier following ENUM keyword"; + case PS_EnumIDSeen: + return "Illegal syntax or missing '{' following enum identifier"; + case PS_EnumSqSeen: + return "Illegal syntax following enum '{' opener"; + case PS_EnumQsSeen: + return "Illegal syntax following enum '}' closer"; + case PS_EnumBodySeen: + return "Illegal syntax following enum enumerator(s)"; + case PS_EnumCommaSeen: + return "Illegal syntax or missing identifier following ',' in enum"; + case PS_SequenceSeen: + return "Illegal syntax or missing '<' following SEQUENCE keyword"; + case PS_SequenceSqSeen: + return "Illegal syntax or missing type following '<' in sequence"; + case PS_SequenceQsSeen: + return "Illegal syntax following '>' in sequence"; + case PS_SequenceTypeSeen: + return "Illegal syntax following sequence type declaration"; + case PS_ArrayIDSeen: + return "Illegal syntax or missing dimensions after array identifier"; + case PS_ArrayCompleted: + return "Illegal syntax after array declaration"; + case PS_DimSqSeen: + return "Illegal syntax or missing size expr after '[' in array declaration"; + case PS_DimQsSeen: + return "Illegal syntax after ']' in array declaration"; + case PS_DimExprSeen: + return "Illegal syntax or missing ']' after size expr in array declaration"; + case PS_FlagHeaderSeen: + return "Illegal syntax after flags"; + case PS_AttrSeen: + return "Illegal syntax after ATTRIBUTE keyword"; + case PS_AttrTypeSeen: + return "Illegal syntax after type in attribute declaration"; + case PS_AttrCompleted: + return "Illegal syntax after attribute declaration"; + case PS_ReadOnlySeen: + return "Illegal syntax after READONLY keyword"; + case PS_OptionalSeen: + return "Illegal syntax after OPTIONAL keyword"; + case PS_MayBeVoidSeen: + return "Illegal syntax after MAYBEVOID keyword"; + case PS_BoundSeen: + return "Illegal syntax after BOUND keyword"; + case PS_ConstrainedSeen: + return "Illegal syntax after CONSTRAINED keyword"; + case PS_TransientSeen: + return "Illegal syntax after TRANSIENT keyword"; + case PS_MayBeAmbigiousSeen: + return "Illegal syntax after MAYBEAMBIGIOUS keyword"; + case PS_MayBeDefaultSeen: + return "Illegal syntax after MAYBEDEFAULT keyword"; + case PS_RemoveableSeen: + return "Illegal syntax after REMOVEABLE keyword"; + case PS_PropertySeen: + return "Illegal syntax after PROPERTY keyword"; + case PS_PropertyTypeSeen: + return "Illegal syntax after type in property declaration"; + case PS_PropertyCompleted: + return "Illegal syntax after property declaration"; + case PS_ExceptSeen: + return "Illegal syntax or missing identifier after EXCEPTION keyword"; + case PS_ExceptHeaderSeen: + return "Missing '{' or illegal syntax following exception inheritance spec"; + case PS_ExceptIDSeen: + return "Illegal syntax or missing '{' after exception identifier"; + case PS_ExceptSqSeen: + return "Illegal syntax after exception '{' opener"; + case PS_ExceptQsSeen: + return "Illegal syntax after exception '}' closer"; + case PS_ExceptBodySeen: + return "Illegal syntax after exception member(s)"; + case PS_OpHeadSeen: + return "Illegasl syntax after operation header"; + case PS_OpTypeSeen: + return "Illegal syntax or missing identifier after operation type"; + case PS_OpIDSeen: + return "Illegal syntax or missing '(' after operation identifier"; + case PS_OpParsCompleted: + return "Illegal syntax after operation parameter list"; + case PS_OpCompleted: + return "Illegal syntax after operation declaration"; + case PS_OpSqSeen: + return "Illegal syntax after operation parameter list '(' opener"; + case PS_OpQsSeen: + return "Illegal syntax after operation parameter list ')' closer"; + case PS_OpParCommaSeen: + return "Illegal syntax or missing direction in parameter declaration"; + case PS_OpParDirSeen: + return "Illegal syntax or missing type in parameter declaration"; + case PS_OpParTypeSeen: + return "Illegal syntax or missing declarator in parameter declaration"; + case PS_OpParDeclSeen: + return "Illegal syntax following parameter declarator"; + case PS_OpOnewaySeen: + return "Illegal syntax after ONEWAY keyword"; + case PS_RaiseSeen: + return "Illegal syntax or missing '(' after RAISES keyword"; + case PS_RaiseSqSeen: + return "Illegal syntax after RAISES '(' opener"; + case PS_RaiseQsSeen: + return "Illegal syntax after RAISES ')' closer"; + case PS_DeclsCommaSeen: + return "Illegal syntax after ',' in declarators list"; + case PS_DeclsDeclSeen: + return "Illegal syntax after declarator in declarators list"; + default: + return "no wider described syntax error"; + } +} + +static OString flagToString(sal_uInt32 flag) +{ + OString flagStr; + if ( (flag & AF_READONLY) == AF_READONLY ) + flagStr += "'readonly'"; + if ( (flag & AF_OPTIONAL) == AF_OPTIONAL ) + flagStr += "'optional'"; + if ( (flag & AF_MAYBEVOID) == AF_MAYBEVOID ) + flagStr += "'maybevoid'"; + if ( (flag & AF_BOUND) == AF_BOUND ) + flagStr += "'bound'"; + if ( (flag & AF_CONSTRAINED) == AF_CONSTRAINED ) + flagStr += "'constrained'"; + if ( (flag & AF_TRANSIENT) == AF_TRANSIENT ) + flagStr += "'transient'"; + if ( (flag & AF_MAYBEAMBIGUOUS) == AF_MAYBEAMBIGUOUS ) + flagStr += "'maybeambiguous'"; + if ( (flag & AF_MAYBEDEFAULT) == AF_MAYBEDEFAULT ) + flagStr += "'maybedefault'"; + if ( (flag & AF_REMOVEABLE) == AF_REMOVEABLE ) + flagStr += "'removeable'"; + if ( (flag & AF_ATTRIBUTE) == AF_ATTRIBUTE ) + flagStr += "'attribute'"; + if ( (flag & AF_PROPERTY) == AF_PROPERTY ) + flagStr += "'property'"; + if ( !flagStr.getLength() ) + flagStr += "'unknown'"; + + return flagStr; +} + +static void errorHeader(ErrorCode eCode, sal_Int32 lineNumber) +{ + OString file; + if ( idlc()->getFileName() == idlc()->getRealFileName() ) + file = idlc()->getMainFileName(); + else + file = idlc()->getFileName(); + + fprintf(stderr, "%s(%lu) : %s", file.getStr(), + sal::static_int_cast< unsigned long >(lineNumber), + errorCodeToMessage(eCode)); +} + +static void errorHeader(ErrorCode eCode) +{ + errorHeader(eCode, idlc()->getLineNumber()); +} + +static void warningHeader(WarningCode wCode) +{ + OString file; + if ( idlc()->getFileName() == idlc()->getRealFileName() ) + file = idlc()->getMainFileName(); + else + file = idlc()->getFileName(); + + fprintf(stderr, "%s(%lu) : WARNING, %s", file.getStr(), + sal::static_int_cast< unsigned long >(idlc()->getLineNumber()), + warningCodeToMessage(wCode)); +} + +void ErrorHandler::error0(ErrorCode e) +{ + errorHeader(e); + fprintf(stderr, "\n"); + idlc()->incErrorCount(); +} + +void ErrorHandler::error1(ErrorCode e, AstDeclaration const * d) +{ + errorHeader(e); + fprintf(stderr, "'%s'\n", d->getScopedName().getStr()); + idlc()->incErrorCount(); +} + +void ErrorHandler::error2( + ErrorCode e, AstDeclaration const * d1, AstDeclaration const * d2) +{ + errorHeader(e); + fprintf(stderr, "'%s', '%s'\n", d1->getScopedName().getStr(), + d2->getScopedName().getStr()); + idlc()->incErrorCount(); +} + +void ErrorHandler::error3(ErrorCode e, AstDeclaration* d1, AstDeclaration* d2, AstDeclaration* d3) +{ + errorHeader(e); + fprintf(stderr, "'%s', '%s', '%s'\n", d1->getScopedName().getStr(), + d2->getScopedName().getStr(), d3->getScopedName().getStr()); + idlc()->incErrorCount(); +} + +void ErrorHandler::warning0(WarningCode w, const sal_Char* warningmsg) +{ + if ( idlc()->getOptions()->isValid("-w") || idlc()->getOptions()->isValid("-we") ) { + warningHeader(w); + fprintf(stderr, "%s\n", warningmsg); + } + + if ( idlc()->getOptions()->isValid("-we") ) + idlc()->incErrorCount(); + else + idlc()->incWarningCount(); +} + +void ErrorHandler::syntaxError(ParseState ps, sal_Int32 lineNumber, const sal_Char* errmsg) +{ + errorHeader(EIDL_SYNTAX_ERROR, lineNumber); + fprintf(stderr, "%s: %s\n", parseStateToMessage(ps), errmsg); + idlc()->incErrorCount(); +} + +void ErrorHandler::coercionError(AstExpression *pExpr, ExprType et) +{ + errorHeader(EIDL_COERCION_FAILURE); + fprintf(stderr, "'%s' to '%s'\n", pExpr->toString().getStr(), + exprTypeToString(et)); + idlc()->incErrorCount(); +} + +void ErrorHandler::lookupError(const ::rtl::OString& n) +{ + errorHeader(EIDL_LOOKUP_ERROR); + fprintf(stderr, "'%s'\n", n.getStr()); + idlc()->incErrorCount(); +} + +void ErrorHandler::lookupError(ErrorCode e, const ::rtl::OString& n, AstDeclaration* pScope) +{ + errorHeader(e); + fprintf(stderr, "'%s' in '%s'\n", n.getStr(), pScope->getFullName().getStr()); + idlc()->incErrorCount(); +} + +void ErrorHandler::flagError(ErrorCode e, sal_uInt32 flag) +{ + errorHeader(e); + fprintf(stderr, "'%s'\n", flagToString(flag).getStr()); + idlc()->incErrorCount(); +} + +void ErrorHandler::noTypeError(AstDeclaration const * pDecl) +{ + errorHeader(EIDL_NOT_A_TYPE); + fprintf(stderr, "'%s'\n", pDecl->getScopedName().getStr()); + idlc()->incErrorCount(); +} + +namespace { + +char const * nodeTypeName(NodeType nodeType) { + switch (nodeType) { + case NT_interface: + return "interface"; + + case NT_exception: + return "exception"; + + case NT_struct: + return "struct"; + + default: + return ""; + } +} + +} + +void ErrorHandler::inheritanceError(NodeType nodeType, const OString* name, AstDeclaration* pDecl) +{ + if ( nodeType == NT_interface && + (pDecl->getNodeType() == NT_interface) && + !((AstInterface*)pDecl)->isDefined() ) + { + errorHeader(EIDL_INHERIT_FWD_ERROR); + fprintf(stderr, "interface '%s' cannot inherit from forward declared interface '%s'\n", + name->getStr(), pDecl->getScopedName().getStr()); + } else + { + errorHeader(EIDL_CANT_INHERIT); + fprintf(stderr, "%s '%s' from '%s'\n", + nodeTypeName(nodeType), name->getStr(), + pDecl->getScopedName().getStr()); + } + idlc()->incErrorCount(); +} + +void ErrorHandler::forwardLookupError(AstDeclaration* pForward, + const ::rtl::OString& name) +{ + errorHeader(EIDL_FWD_DECL_LOOKUP); + fprintf(stderr, "trying to look up '%s' in undefined forward declared interface '%s'\n", + pForward->getScopedName().getStr(), name.getStr()); + idlc()->incErrorCount(); +} + +void ErrorHandler::constantExpected(AstDeclaration* pDecl, + const ::rtl::OString& name) +{ + errorHeader(EIDL_CONSTANT_EXPECTED); + fprintf(stderr, "'%s' is bound to '%s'\n", name.getStr(), pDecl->getScopedName().getStr()); + idlc()->incErrorCount(); +} + +void ErrorHandler::evalError(AstExpression* pExpr) +{ + errorHeader(EIDL_EVAL_ERROR); + fprintf(stderr, "'%s'\n", pExpr->toString().getStr()); + idlc()->incErrorCount(); +} + +void ErrorHandler::enumValExpected(AstUnion* pUnion) +{ + errorHeader(EIDL_ENUM_VAL_EXPECTED); + fprintf(stderr, " union %s\n", pUnion->getLocalName().getStr()); + idlc()->incErrorCount(); +} + +void ErrorHandler::enumValLookupFailure(AstUnion* pUnion, AstEnum* pEnum, const ::rtl::OString& name) +{ + errorHeader(EIDL_ENUM_VAL_NOT_FOUND); + fprintf(stderr, " union %s, enum %s, enumerator %s\n", + pUnion->getLocalName().getStr(), + pEnum->getLocalName().getStr(), name.getStr()); + idlc()->incErrorCount(); +} + +bool ErrorHandler::checkPublished(AstDeclaration const * decl, bool bOptional) { + if (idlc()->isPublished() && !decl->isPublished() && !bOptional) { + error1(EIDL_PUBLISHED_USES_UNPUBLISHED, decl); + return false; + } else { + return true; + } +} diff --git a/idlc/source/fehelper.cxx b/idlc/source/fehelper.cxx new file mode 100644 index 000000000000..cd96c4c2a20a --- /dev/null +++ b/idlc/source/fehelper.cxx @@ -0,0 +1,144 @@ +/************************************************************************* + * + * 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_idlc.hxx" +#include <idlc/fehelper.hxx> +#include <idlc/errorhandler.hxx> +#include <idlc/astarray.hxx> +#include "idlc/idlc.hxx" + +using namespace ::rtl; + +FeDeclarator::FeDeclarator(const OString& name, DeclaratorType declType, AstDeclaration* pComplPart) + : m_pComplexPart(pComplPart) + , m_name(name) + , m_declType(declType) +{ +} + +FeDeclarator::~FeDeclarator() +{ +} + +sal_Bool FeDeclarator::checkType(AstDeclaration const * type) +{ + OString tmp(m_name); + sal_Int32 count = m_name.lastIndexOf( ':' ); + if( count != -1 ) + tmp = m_name.copy( count+1 ); + + if (tmp == type->getLocalName()) + return sal_False; + else + return sal_True; +} + +AstType const * FeDeclarator::compose(AstDeclaration const * pDecl) +{ + AstArray* pArray; + AstType* pType; + + if ( pDecl == 0 ) + { + return NULL; + } + if ( !pDecl->isType() ) + { + idlc()->error()->noTypeError(pDecl); + return NULL; + } + pType = (AstType*)pDecl; + if (m_declType == FD_simple || m_pComplexPart == NULL) + return pType; + + if (m_pComplexPart->getNodeType() == NT_array) + { + pArray = (AstArray*)m_pComplexPart; + pArray->setType(pType); + + // insert array type in global scope + AstScope* pScope = idlc()->scopes()->bottom(); + if ( pScope ) + { + AstDeclaration* pDecl2 = pScope->addDeclaration(pArray); + if ( (AstDeclaration*)pArray != pDecl2 ) + { + delete m_pComplexPart; + m_pComplexPart = pDecl2; + } + } + return pArray; + } + + return NULL; // return through this statement should not happen +} + +FeInheritanceHeader::FeInheritanceHeader( + NodeType nodeType, ::rtl::OString* pName, ::rtl::OString* pInherits, + std::vector< rtl::OString > * typeParameters) + : m_nodeType(nodeType) + , m_pName(pName) + , m_pInherits(NULL) +{ + if (typeParameters != 0) { + m_typeParameters = *typeParameters; + } + initializeInherits(pInherits); +} + +void FeInheritanceHeader::initializeInherits(::rtl::OString* pInherits) +{ + if ( pInherits ) + { + AstScope* pScope = idlc()->scopes()->topNonNull(); + AstDeclaration* pDecl = pScope->lookupByName(*pInherits); + if ( pDecl ) + { + AstDeclaration const * resolved = resolveTypedefs(pDecl); + if ( resolved->getNodeType() == getNodeType() + && (resolved->getNodeType() != NT_interface + || static_cast< AstInterface const * >( + resolved)->isDefined()) ) + { + if ( idlc()->error()->checkPublished( pDecl ) ) + { + m_pInherits = pDecl; + } + } + else + { + idlc()->error()->inheritanceError( + getNodeType(), getName(), pDecl); + } + } + else + { + idlc()->error()->lookupError(*pInherits); + } + } +} diff --git a/idlc/source/idlc.cxx b/idlc/source/idlc.cxx new file mode 100644 index 000000000000..1477739cd531 --- /dev/null +++ b/idlc/source/idlc.cxx @@ -0,0 +1,341 @@ +/************************************************************************* + * + * 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_idlc.hxx" +#include <idlc/idlc.hxx> +#include <idlc/errorhandler.hxx> +#include <idlc/astscope.hxx> +#include <idlc/astmodule.hxx> +#include <idlc/astservice.hxx> +#include <idlc/astconstants.hxx> +#include <idlc/astexception.hxx> +#include <idlc/astunion.hxx> +#include <idlc/astenum.hxx> +#include <idlc/astinterface.hxx> +#include <idlc/astoperation.hxx> +#include <idlc/astbasetype.hxx> +#include "idlc/astdeclaration.hxx" +#include "idlc/astparameter.hxx" +#include "idlc/astsequence.hxx" +#include "idlc/asttype.hxx" +#include "idlc/asttypedef.hxx" + +#include "osl/diagnose.h" + +using namespace ::rtl; + +AstDeclaration* SAL_CALL scopeAsDecl(AstScope* pScope) +{ + if (pScope == NULL) return NULL; + + switch( pScope->getScopeNodeType() ) + { + case NT_service: + case NT_singleton: + return (AstService*)(pScope); + case NT_module: + case NT_root: + return (AstModule*)(pScope); + case NT_constants: + return (AstConstants*)(pScope); + case NT_interface: + return (AstInterface*)(pScope); + case NT_operation: + return (AstOperation*)(pScope); + case NT_exception: + return (AstException*)(pScope); + case NT_union: + return (AstUnion*)(pScope); + case NT_struct: + return (AstStruct*)(pScope); + case NT_enum: + return (AstEnum*)(pScope); + default: + return NULL; + } +} + +AstScope* SAL_CALL declAsScope(AstDeclaration* pDecl) +{ + if (pDecl == NULL) return NULL; + + switch(pDecl->getNodeType()) + { + case NT_interface: + return (AstInterface*)(pDecl); + case NT_service: + case NT_singleton: + return (AstService*)(pDecl); + case NT_module: + case NT_root: + return (AstModule*)(pDecl); + case NT_constants: + return (AstConstants*)(pDecl); + case NT_exception: + return (AstException*)(pDecl); + case NT_union: + return (AstUnion*)(pDecl); + case NT_struct: + return (AstStruct*)(pDecl); + case NT_enum: + return (AstEnum*)(pDecl); + case NT_operation: + return (AstOperation*)(pDecl); + default: + return NULL; + } +} + +static void SAL_CALL predefineXInterface(AstModule* pRoot) +{ + // define the modules com::sun::star::uno + AstModule* pParentScope = pRoot; + AstModule* pModule = new AstModule(OString("com"), pParentScope); + pModule->setPredefined(true); + pParentScope->addDeclaration(pModule); + pParentScope = pModule; + pModule = new AstModule(OString("sun"), pParentScope); + pModule->setPredefined(true); + pParentScope->addDeclaration(pModule); + pParentScope = pModule; + pModule = new AstModule(OString("star"), pParentScope); + pModule->setPredefined(true); + pParentScope->addDeclaration(pModule); + pParentScope = pModule; + pModule = new AstModule(OString("uno"), pParentScope); + pModule->setPredefined(true); + pParentScope->addDeclaration(pModule); + pParentScope = pModule; + + // define XInterface + AstInterface* pInterface = new AstInterface(OString("XInterface"), NULL, pParentScope); + pInterface->setDefined(); + pInterface->setPredefined(true); + pInterface->setPublished(); + pParentScope->addDeclaration(pInterface); + + // define XInterface::queryInterface + AstOperation* pOp = new AstOperation(0, (AstType*)(pRoot->lookupPrimitiveType(ET_any)), + OString("queryInterface"), pInterface); + AstParameter* pParam = new AstParameter(DIR_IN, false, + (AstType*)(pRoot->lookupPrimitiveType(ET_type)), + OString("aType"), pOp); + pOp->addDeclaration(pParam); + pInterface->addMember(pOp); + + // define XInterface::acquire + pOp = new AstOperation(1, (AstType*)(pRoot->lookupPrimitiveType(ET_void)), + OString("acquire"), pInterface); + pInterface->addMember(pOp); + + // define XInterface::release + pOp = new AstOperation(1, (AstType*)(pRoot->lookupPrimitiveType(ET_void)), + OString("release"), pInterface); + pInterface->addMember(pOp); +} + +static void SAL_CALL initializePredefinedTypes(AstModule* pRoot) +{ + AstBaseType* pPredefined = NULL; + if ( pRoot ) + { + pPredefined = new AstBaseType(ET_long, OString("long"), pRoot); + pRoot->addDeclaration(pPredefined); + + pPredefined = new AstBaseType(ET_ulong, OString("unsigned long"), pRoot); + pRoot->addDeclaration(pPredefined); + + pPredefined = new AstBaseType(ET_hyper, OString("hyper"), pRoot); + pRoot->addDeclaration(pPredefined); + + pPredefined = new AstBaseType(ET_uhyper, OString("unsigned hyper"), pRoot); + pRoot->addDeclaration(pPredefined); + + pPredefined = new AstBaseType(ET_short, OString("short"), pRoot); + pRoot->addDeclaration(pPredefined); + + pPredefined = new AstBaseType(ET_ushort, OString("unsigned short"), pRoot); + pRoot->addDeclaration(pPredefined); + + pPredefined = new AstBaseType(ET_float, OString("float"), pRoot); + pRoot->addDeclaration(pPredefined); + + pPredefined = new AstBaseType(ET_double, OString("double"), pRoot); + pRoot->addDeclaration(pPredefined); + + pPredefined = new AstBaseType(ET_char, OString("char"), pRoot); + pRoot->addDeclaration(pPredefined); + + pPredefined = new AstBaseType(ET_byte, OString("byte"), pRoot); + pRoot->addDeclaration(pPredefined); + + pPredefined = new AstBaseType(ET_any, OString("any"), pRoot); + pRoot->addDeclaration(pPredefined); + + pPredefined = new AstBaseType(ET_string, OString("string"), pRoot); + pRoot->addDeclaration(pPredefined); + + pPredefined = new AstBaseType(ET_type, OString("type"), pRoot); + pRoot->addDeclaration(pPredefined); + + pPredefined = new AstBaseType(ET_boolean, OString("boolean"), pRoot); + pRoot->addDeclaration(pPredefined); + + pPredefined = new AstBaseType(ET_void, OString("void"), pRoot); + pRoot->addDeclaration(pPredefined); + } +} + +Idlc::Idlc(Options* pOptions) + : m_pOptions(pOptions) + , m_bIsDocValid(sal_False) + , m_bIsInMainfile(sal_True) + , m_published(false) + , m_errorCount(0) + , m_warningCount(0) + , m_lineNumber(0) + , m_parseState(PS_NoState) +{ + m_pScopes = new AstStack(); + // init root object after construction + m_pRoot = NULL; + m_pErrorHandler = new ErrorHandler(); + m_bGenerateDoc = m_pOptions->isValid("-C"); +} + +Idlc::~Idlc() +{ + if (m_pRoot) + delete m_pRoot; + if (m_pScopes) + delete m_pScopes; + if (m_pErrorHandler) + delete m_pErrorHandler; +} + +void Idlc::init() +{ + if ( m_pRoot ) + delete m_pRoot; + + m_pRoot = new AstModule(NT_root, OString(), NULL); + + // push the root node on the stack + m_pScopes->push(m_pRoot); + initializePredefinedTypes(m_pRoot); + predefineXInterface(m_pRoot); +} + +void Idlc::reset() +{ + m_bIsDocValid = sal_False; + m_bIsInMainfile = sal_True; + m_published = false; + + m_errorCount = 0; + m_warningCount = 0; + m_lineNumber = 0; + m_parseState = PS_NoState; + + m_fileName = OString(); + m_mainFileName = OString(); + m_realFileName = OString(); + m_documentation = OString(); + + m_pScopes->clear(); + if ( m_pRoot) + delete m_pRoot; + + m_pRoot = new AstModule(NT_root, OString(), NULL); + + // push the root node on the stack + m_pScopes->push(m_pRoot); + initializePredefinedTypes(m_pRoot); +} + +sal_Bool Idlc::isDocValid() +{ + if ( m_bGenerateDoc ) + return m_bIsDocValid; + return sal_False;; +} + +static Idlc* pStaticIdlc = NULL; + +Idlc* SAL_CALL idlc() +{ + return pStaticIdlc; +} + +Idlc* SAL_CALL setIdlc(Options* pOptions) +{ + if ( pStaticIdlc ) + { + delete pStaticIdlc; + } + pStaticIdlc = new Idlc(pOptions); + pStaticIdlc->init(); + return pStaticIdlc; +} + +AstDeclaration const * resolveTypedefs(AstDeclaration const * type) { + if (type != 0) { + while (type->getNodeType() == NT_typedef) { + type = static_cast< AstTypeDef const * >(type)->getBaseType(); + } + } + return type; +} + +AstDeclaration const * deconstructAndResolveTypedefs( + AstDeclaration const * type, sal_Int32 * rank) +{ + *rank = 0; + for (;;) { + if (type == 0) { + return 0; + } + switch (type->getNodeType()) { + case NT_typedef: + type = static_cast< AstTypeDef const * >(type)->getBaseType(); + break; + case NT_sequence: + ++(*rank); + type = static_cast< AstSequence const * >(type)->getMemberType(); + break; + default: + return type; + } + } +} + +AstInterface const * resolveInterfaceTypedefs(AstType const * type) { + AstDeclaration const * decl = resolveTypedefs(type); + OSL_ASSERT(decl->getNodeType() == NT_interface); + return static_cast< AstInterface const * >(decl); +} diff --git a/idlc/source/idlccompile.cxx b/idlc/source/idlccompile.cxx new file mode 100644 index 000000000000..26bf288e2ad0 --- /dev/null +++ b/idlc/source/idlccompile.cxx @@ -0,0 +1,418 @@ +/************************************************************************* + * + * 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_idlc.hxx" +#include <idlc/idlc.hxx> +#include <rtl/ustring.hxx> +#include <rtl/strbuf.hxx> +#include <osl/process.h> +#include <osl/diagnose.h> +#include <osl/thread.h> +#include <osl/file.hxx> + +#if defined(SAL_W32) || defined(SAL_OS2) +#include <io.h> +#endif + +#ifdef SAL_UNX +#include <unistd.h> +#if defined(MACOSX) || defined(FREEBSD) || defined(NETBSD) +#include <sys/wait.h> +#else +#include <wait.h> +#endif +#endif + +#include <string.h> + +using namespace ::rtl; +using namespace ::osl; + +extern int yyparse(); +extern FILE* yyin; +extern int yydebug; + +sal_Int32 lineNumber = 1; + + +static OUString TMP(RTL_CONSTASCII_USTRINGPARAM("TMP")); +static OUString TEMP(RTL_CONSTASCII_USTRINGPARAM("TEMP")); +static sal_Char tmpFilePattern[512]; + +sal_Bool isFileUrl(const OString& fileName) +{ + if (fileName.indexOf("file://") == 0 ) + return sal_True; + return sal_False; +} + +OString convertToAbsoluteSystemPath(const OString& fileName) +{ + OUString uSysFileName; + OUString uFileName(fileName.getStr(), fileName.getLength(), osl_getThreadTextEncoding()); + if ( isFileUrl(fileName) ) + { + if (FileBase::getSystemPathFromFileURL(uFileName, uSysFileName) + != FileBase::E_None) + { + OSL_ASSERT(false); + } + } else + { + OUString uWorkingDir, uUrlFileName, uTmp; + if (osl_getProcessWorkingDir(&uWorkingDir.pData) != osl_Process_E_None) + { + OSL_ASSERT(false); + } + if (FileBase::getFileURLFromSystemPath(uFileName, uTmp) + != FileBase::E_None) + { + OSL_ASSERT(false); + } + if (FileBase::getAbsoluteFileURL(uWorkingDir, uTmp, uUrlFileName) + != FileBase::E_None) + { + OSL_ASSERT(false); + } + if (FileBase::getSystemPathFromFileURL(uUrlFileName, uSysFileName) + != FileBase::E_None) + { + OSL_ASSERT(false); + } + } + + return OUStringToOString(uSysFileName, osl_getThreadTextEncoding()); +} + +OString convertToFileUrl(const OString& fileName) +{ + if ( !isFileUrl(fileName) ) + { + OString tmp = convertToAbsoluteSystemPath(fileName); + OUString uFileName(tmp.getStr(), tmp.getLength(), osl_getThreadTextEncoding()); + OUString uUrlFileName; + if (FileBase::getFileURLFromSystemPath(uFileName, uUrlFileName) + != FileBase::E_None) + { + OSL_ASSERT(false); + } + return OUStringToOString(uUrlFileName, osl_getThreadTextEncoding()); + } + + return fileName; +} + +OString makeTempName(const OString& prefix) +{ + OUString uTmpPath; + OString tmpPath; + + if ( osl_getEnvironment(TMP.pData, &uTmpPath.pData) != osl_Process_E_None ) + { + if ( osl_getEnvironment(TEMP.pData, &uTmpPath.pData) != osl_Process_E_None ) + { +#if defined(SAL_W32) + tmpPath = OString("c:\\temp"); +#else + tmpPath = OString("/tmp"); +#endif + } + } + + if ( uTmpPath.getLength() ) + tmpPath = OUStringToOString(uTmpPath, RTL_TEXTENCODING_UTF8); + +#if defined(SAL_W32) || defined(SAL_UNX) || defined(SAL_OS2) + + OSL_ASSERT( sizeof(tmpFilePattern) > ( strlen(tmpPath) + + RTL_CONSTASCII_LENGTH( + PATH_SEPARATOR ) + + prefix.getLength() + + RTL_CONSTASCII_LENGTH( + "XXXXXX") ) ); + + tmpFilePattern[ sizeof(tmpFilePattern)-1 ] = '\0'; + strncpy(tmpFilePattern, tmpPath, sizeof(tmpFilePattern)-1); + strncat(tmpFilePattern, PATH_SEPARATOR, sizeof(tmpFilePattern)-1-strlen(tmpFilePattern)); + strncat(tmpFilePattern, prefix.getStr(), sizeof(tmpFilePattern)-1-strlen(tmpFilePattern)); + strncat(tmpFilePattern, "XXXXXX", sizeof(tmpFilePattern)-1-strlen(tmpFilePattern)); + +#ifdef SAL_UNX + int nDescriptor = mkstemp(tmpFilePattern); + if( -1 == nDescriptor ) + { + fprintf( stderr,"idlc: couldn't create temporary file\n" ); + exit( 1 ); + } + // the file shall later be reopened by stdio functions + close( nDescriptor ); +#else + (void) mktemp(tmpFilePattern); +#endif +#endif + + return OString(tmpFilePattern); +} + +sal_Bool copyFile(const OString* source, const OString& target) +{ + sal_Bool bRet = sal_True; + + FILE* pSource = source == 0 ? stdin : fopen(source->getStr(), "rb"); + + if ( !pSource ) + return sal_False; + + FILE* pTarget = fopen(target.getStr(), "wb"); + + if ( !pTarget ) + { + fclose(pSource); + return sal_False; + } + + size_t totalSize = 512; + size_t readSize = 0; + size_t writeSize = 0; + char pBuffer[513]; + + while ( !feof(pSource) ) + { + if ( (readSize = fread(pBuffer, 1, totalSize, pSource)) > 0 && !ferror(pSource) ) + { + if ( (writeSize = fwrite(pBuffer, 1, readSize, pTarget)) != readSize || ferror(pTarget) ) + { + if (source != 0) { + fclose(pSource); + } + fclose(pTarget); + return sal_False; + } + } + } + + if (source != 0) { + fclose(pSource); + } + if ( fflush(pTarget) ) + bRet = sal_False; + fclose(pTarget); + + return bRet; +} + +sal_Int32 compileFile(const OString * pathname) +{ + // preprocess input file + OString tmpFile = makeTempName(OString("idli_")); + OString preprocFile = makeTempName(OString("idlf_")); + + OString fileName; + if (pathname == 0) { + fileName = "stdin"; + } else { + fileName = *pathname; + } + + if ( !copyFile(pathname, tmpFile) ) + { + fprintf(stderr, "%s: could not copy %s%s to %s\n", + idlc()->getOptions()->getProgramName().getStr(), + pathname == 0 ? "" : "file ", fileName.getStr(), + tmpFile.getStr()); + exit(99); + } + + idlc()->setFileName(fileName); + idlc()->setMainFileName(fileName); + idlc()->setRealFileName(tmpFile); + + OStringBuffer cppArgs(512); + cppArgs.append("-DIDL -Xi -Xc -+ -I."); + Options* pOptions = idlc()->getOptions(); + + OString filePath; + sal_Int32 index = fileName.lastIndexOf(SEPARATOR); + + if ( index > 0) + { + filePath = fileName.copy(0, index); + + if ( filePath.getLength() ) + { + cppArgs.append(" -I\""); + cppArgs.append(filePath); + cppArgs.append("\""); + } + } + + if ( pOptions->isValid("-D") ) + { + cppArgs.append(" "); + cppArgs.append(pOptions->getOption("-D")); + } + if ( pOptions->isValid("-I") ) + { + cppArgs.append(" "); + cppArgs.append(pOptions->getOption("-I")); + } + + cppArgs.append(" \""); + cppArgs.append(tmpFile); + cppArgs.append("\" \""); + cppArgs.append(preprocFile); + cppArgs.append("\""); + + OString cmdFileName = makeTempName(OString("idlc_")); + FILE* pCmdFile = fopen(cmdFileName, "w"); + + if ( !pCmdFile ) + { + fprintf(stderr, "%s: couldn't open temporary file for preprocessor commands: %s\n", + idlc()->getOptions()->getProgramName().getStr(), cmdFileName.getStr()); + exit(99); + } +#ifdef SAL_OS2_00 + char* tok = strtok( (char*)cppArgs.getStr(), " \t\n\r"); + while( tok) { + if (tok[strlen(tok)-1] == '\"') + tok[strlen(tok)-1] = '\0'; + if (*tok == '\"') + memcpy( tok, tok+1, strlen(tok)); + if (strlen(tok)>0) { + fputs(tok, pCmdFile); + fputc('\n', pCmdFile); + } + tok = strtok( NULL, " \t\n\r"); + } +#else + fprintf(pCmdFile, "%s", cppArgs.getStr()); +#endif + fclose(pCmdFile); + + OUString cmdArg(RTL_CONSTASCII_USTRINGPARAM("@")); + cmdArg += OStringToOUString(cmdFileName, RTL_TEXTENCODING_UTF8); + + OUString cpp; + OUString startDir; + if (osl_getExecutableFile(&cpp.pData) != osl_Process_E_None) { + OSL_ASSERT(false); + } + + sal_Int32 idx= cpp.lastIndexOf(OUString( RTL_CONSTASCII_USTRINGPARAM("idlc")) ); + cpp = cpp.copy(0, idx); + +#if defined(SAL_W32) || defined(SAL_OS2) + cpp += OUString( RTL_CONSTASCII_USTRINGPARAM("idlcpp.exe")); +#else + cpp += OUString( RTL_CONSTASCII_USTRINGPARAM("idlcpp")); +#endif + + oslProcess hProcess = NULL; + oslProcessError procError = osl_Process_E_None; + + procError = osl_executeProcess(cpp.pData, &cmdArg.pData, 1, osl_Process_WAIT, + 0, startDir.pData, 0, 0, &hProcess); + + oslProcessInfo hInfo; + hInfo.Size = (sal_uInt32)(sizeof(oslProcessInfo)); + if (osl_getProcessInfo(hProcess, osl_Process_EXITCODE, &hInfo) + != osl_Process_E_None) + { + OSL_ASSERT(false); + } + + if ( procError || (hInfo.Code != 0) ) + { + if ( procError != osl_Process_E_None ) + fprintf(stderr, "%s: starting preprocessor failed\n", pOptions->getProgramName().getStr()); + else + fprintf(stderr, "%s: preprocessing %s%s failed\n", + pOptions->getProgramName().getStr(), + pathname == 0 ? "" : "file ", fileName.getStr()); + + unlink(tmpFile.getStr()); + unlink(preprocFile.getStr()); + unlink(cmdFileName.getStr()); + osl_freeProcessHandle(hProcess); + exit(hInfo.Code ? hInfo.Code : 99); + } + osl_freeProcessHandle(hProcess); + + if (unlink(tmpFile.getStr()) != 0) + { + fprintf(stderr, "%s: Could not remove cpp input file %s\n", + pOptions->getProgramName().getStr(), tmpFile.getStr()); + exit(99); + } + + if (unlink(cmdFileName.getStr()) != 0) + { + fprintf(stderr, "%s: Could not remove unocpp command file %s\n", + pOptions->getProgramName().getStr(), cmdFileName.getStr()); + + exit(99); + } + + if ( pOptions->isValid("-E") ) + { + if (unlink(preprocFile) != 0) + { + fprintf(stderr, "%s: Could not remove parser input file %s\n", + pOptions->getProgramName().getStr(), preprocFile.getStr()); + exit(99); + } + exit(0); + } + + // parse file + yyin = fopen(preprocFile.getStr(), "r"); + if (yyin == NULL) + { + fprintf(stderr, "%s: Could not open cpp output file %s\n", + pOptions->getProgramName().getStr(), preprocFile.getStr()); + exit(99); + } + + //yydebug = 0 no trace information + //yydebug = 1 parser produce trace information + yydebug = 0; + + sal_Int32 nErrors = yyparse(); + nErrors = idlc()->getErrorCount(); + + fclose(yyin); + if (unlink(preprocFile.getStr()) != 0) + { + fprintf(stderr, "%s: Could not remove parser input file %s\n", + pOptions->getProgramName().getStr(), preprocFile.getStr()); + exit(99); + } + + return nErrors; +} diff --git a/idlc/source/idlcmain.cxx b/idlc/source/idlcmain.cxx new file mode 100644 index 000000000000..006131f727df --- /dev/null +++ b/idlc/source/idlcmain.cxx @@ -0,0 +1,148 @@ +/************************************************************************* + * + * 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_idlc.hxx" +#include <idlc/idlc.hxx> +#include "sal/main.h" + +using namespace ::rtl; + +SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv) +{ + Options options; + + try + { + if (!options.initOptions(argc, argv)) + exit(1); + } + catch( IllegalArgument& e) + { + fprintf(stderr, "Illegal argument: %s\n%s", + e.m_message.getStr(), + options.prepareVersion().getStr()); + exit(99); + } + + setIdlc(&options); + + sal_Int32 nErrors = 0; + if (options.readStdin()) { + if ( !options.quiet() ) + fprintf( + stdout, "%s: Compiling stdin\n", + options.getProgramName().getStr()); + nErrors = compileFile(0); + if ( ( idlc()->getWarningCount() > 0 ) && !options.quiet() ) { + fprintf( + stdout, "%s: detected %lu warnings compiling stdin\n", + options.getProgramName().getStr(), + sal::static_int_cast< unsigned long >( + idlc()->getWarningCount())); + } + OString outputUrl; + if (options.isValid("-O")) { + outputUrl = convertToFileUrl(options.getOption("-O")); + if (outputUrl[outputUrl.getLength() - 1] != '/') { + outputUrl += "/"; + } + outputUrl += "stdin.urd"; + } else { + outputUrl = convertToFileUrl("stdin.urd"); + } + if (nErrors > 0) { + removeIfExists(outputUrl); + } else { + nErrors = produceFile(outputUrl); + } + idlc()->reset(); + } + StringVector const & files = options.getInputFiles(); + if ( options.verbose() ) + { + fprintf( stdout, "%s: compiling %i source files ... \n", + options.getProgramName().getStr(), (int)files.size() ); + fflush( stdout ); + } + for (StringVector::const_iterator i(files.begin()); + i != files.end() && nErrors == 0; ++i) + { + OString sysFileName( convertToAbsoluteSystemPath(*i) ); + + if ( !options.quiet() ) + fprintf(stdout, "Compiling: %s\n", + (*i).getStr()); + nErrors = compileFile(&sysFileName); + + if ( idlc()->getWarningCount() && !options.quiet() ) + fprintf(stdout, "%s: detected %lu warnings compiling file '%s'\n", + options.getProgramName().getStr(), + sal::static_int_cast< unsigned long >( + idlc()->getWarningCount()), + (*i).getStr()); + + // prepare output file name + OString outputFileUrl; + if ( options.isValid("-O") ) + { + OString strippedFileName(sysFileName.copy(sysFileName.lastIndexOf(SEPARATOR) + 1)); + outputFileUrl = convertToFileUrl(options.getOption("-O")); + sal_Char c = outputFileUrl.getStr()[outputFileUrl.getLength()-1]; + + if ( c != '/' ) + outputFileUrl += OString::valueOf('/'); + + outputFileUrl += strippedFileName.replaceAt(strippedFileName.getLength() -3 , 3, "urd"); + } else + { + outputFileUrl = convertToFileUrl(sysFileName.replaceAt(sysFileName.getLength() -3 , 3, "urd")); + } + + if ( nErrors ) + removeIfExists(outputFileUrl); + else + nErrors = produceFile(outputFileUrl); + + idlc()->reset(); + } + + if ( nErrors > 0 ) + { + fprintf(stderr, "%s: detected %ld errors%s", + options.getProgramName().getStr(), + sal::static_int_cast< long >(nErrors), + options.prepareVersion().getStr()); + } else + { + if ( options.verbose() ) + fprintf(stdout, "%s: returned successful%s", + options.getProgramName().getStr(), + options.prepareVersion().getStr()); + } + return nErrors; +} diff --git a/idlc/source/idlcproduce.cxx b/idlc/source/idlcproduce.cxx new file mode 100644 index 000000000000..e20b7da1c42b --- /dev/null +++ b/idlc/source/idlcproduce.cxx @@ -0,0 +1,210 @@ +/************************************************************************* + * + * 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_idlc.hxx" +#include <idlc/idlc.hxx> +#include <idlc/astmodule.hxx> +#include <rtl/strbuf.hxx> +#include <osl/file.hxx> +#include <osl/thread.h> + +#if defined(SAL_W32) || defined(SAL_OS2) +#include <io.h> +#include <direct.h> +#include <errno.h> +#endif + +#ifdef SAL_UNX +#include <unistd.h> +#include <sys/stat.h> +#include <errno.h> +#endif + +#include <string.h> + +using namespace ::rtl; +using namespace ::osl; + +StringList* pCreatedDirectories = NULL; + +static sal_Bool checkOutputPath(const OString& completeName) +{ + OString sysPathName = convertToAbsoluteSystemPath(completeName); + OStringBuffer buffer(sysPathName.getLength()); + + if ( sysPathName.indexOf( SEPARATOR ) == -1 ) + return sal_True; + + sal_Int32 nIndex = 0; + OString token(sysPathName.getToken(0, SEPARATOR, nIndex)); + const sal_Char* p = token.getStr(); + if (strcmp(p, "..") == 0 + || *(p+1) == ':' + || strcmp(p, ".") == 0) + { + buffer.append(token); + buffer.append(SEPARATOR); + } + else + nIndex = 0; + + do + { + buffer.append(sysPathName.getToken(0, SEPARATOR, nIndex)); + + if ( buffer.getLength() > 0 && nIndex != -1 ) + { +#if defined(SAL_UNX) || defined(SAL_OS2) + if (mkdir((char*)buffer.getStr(), 0777) == -1) +#else + if (mkdir((char*)buffer.getStr()) == -1) +#endif + { + if (errno == ENOENT) + { + fprintf(stderr, "%s: cannot create directory '%s'\n", + idlc()->getOptions()->getProgramName().getStr(), buffer.getStr()); + return sal_False; + } + } else + { + if ( !pCreatedDirectories ) + pCreatedDirectories = new StringList(); + pCreatedDirectories->push_front(buffer.getStr()); + } + } + buffer.append(SEPARATOR); + } while( nIndex != -1 ); + return sal_True; +} + +static sal_Bool cleanPath() +{ + if ( pCreatedDirectories ) + { + StringList::iterator iter = pCreatedDirectories->begin(); + StringList::iterator end = pCreatedDirectories->end(); + while ( iter != end ) + { +//#ifdef SAL_UNX +// if (rmdir((char*)(*iter).getStr(), 0777) == -1) +//#else + if (rmdir((char*)(*iter).getStr()) == -1) +//#endif + { + fprintf(stderr, "%s: cannot remove directory '%s'\n", + idlc()->getOptions()->getProgramName().getStr(), (*iter).getStr()); + return sal_False; + } + ++iter; + } + delete pCreatedDirectories; + } + return sal_True; +} + +void removeIfExists(const OString& pathname) +{ + unlink(pathname.getStr()); +} + +sal_Int32 SAL_CALL produceFile(const OString& regFileName) +{ + Options* pOptions = idlc()->getOptions(); + + OString regTmpName = regFileName.replaceAt(regFileName.getLength() -3, 3, "_idlc_"); + + if ( !checkOutputPath(regFileName) ) + { + fprintf(stderr, "%s: could not create path of registry file '%s'.\n", + pOptions->getProgramName().getStr(), regFileName.getStr()); + return 1; + } + + removeIfExists(regTmpName); + OString urlRegTmpName = convertToFileUrl(regTmpName); + + Registry regFile; + if ( regFile.create(OStringToOUString(urlRegTmpName, RTL_TEXTENCODING_UTF8)) != REG_NO_ERROR ) + { + fprintf(stderr, "%s: could not create registry file '%s'\n", + pOptions->getProgramName().getStr(), regTmpName.getStr()); + removeIfExists(regTmpName); + removeIfExists(regFileName); + cleanPath(); + return 1; + } + + RegistryKey rootKey; + if ( regFile.openRootKey(rootKey) != REG_NO_ERROR ) + { + fprintf(stderr, "%s: could not open root of registry file '%s'\n", + pOptions->getProgramName().getStr(), regFileName.getStr()); + removeIfExists(regTmpName); + removeIfExists(regFileName); + cleanPath(); + return 1; + } + + // produce registry file + if ( !idlc()->getRoot()->dump(rootKey) ) + { + rootKey.releaseKey(); + regFile.close(); + regFile.destroy(OStringToOUString(regFileName, RTL_TEXTENCODING_UTF8)); + removeIfExists(regFileName); + cleanPath(); + return 1; + } + + rootKey.releaseKey(); + if ( regFile.close() != REG_NO_ERROR ) + { + fprintf(stderr, "%s: could not close registry file '%s'\n", + pOptions->getProgramName().getStr(), regFileName.getStr()); + removeIfExists(regTmpName); + removeIfExists(regFileName); + cleanPath(); + return 1; + } + + removeIfExists(regFileName); + + if ( File::move(OStringToOUString(regTmpName, osl_getThreadTextEncoding()), + OStringToOUString(regFileName, osl_getThreadTextEncoding())) != FileBase::E_None ) { + fprintf(stderr, "%s: cannot rename temporary registry '%s' to '%s'\n", + idlc()->getOptions()->getProgramName().getStr(), + regTmpName.getStr(), regFileName.getStr()); + removeIfExists(regTmpName); + cleanPath(); + return 1; + } + removeIfExists(regTmpName); + + return 0; +} diff --git a/idlc/source/makefile.mk b/idlc/source/makefile.mk new file mode 100644 index 000000000000..879090d15b54 --- /dev/null +++ b/idlc/source/makefile.mk @@ -0,0 +1,129 @@ +#************************************************************************* +# +# 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=idlc +TARGET=idlc +TARGETTYPE=CUI +LIBTARGET=NO + +ENABLE_EXCEPTIONS=TRUE +INCPRE=$(MISC) + +.IF "$(GUI)" == "OS2" +STL_OS2_BUILDING=1 +.ENDIF + +# --- Settings ----------------------------------------------------- + + +.INCLUDE : settings.mk + +# --- Files -------------------------------------------------------- + +CXXFILES= \ + wrap_scanner.cxx \ + wrap_parser.cxx \ + idlcmain.cxx \ + idlc.cxx \ + idlccompile.cxx \ + idlcproduce.cxx \ + errorhandler.cxx \ + options.cxx \ + fehelper.cxx \ + astdeclaration.cxx \ + astscope.cxx \ + aststack.cxx \ + astdump.cxx \ + astinterface.cxx \ + aststruct.cxx \ + aststructinstance.cxx \ + astoperation.cxx \ + astconstant.cxx \ + astenum.cxx \ + astarray.cxx \ + astunion.cxx \ + astexpression.cxx \ + astservice.cxx + +YACCTARGET=$(MISC)$/parser.cxx +YACCFILES=parser.y + +OBJFILES= \ + $(OBJ)$/wrap_scanner.obj \ + $(OBJ)$/wrap_parser.obj \ + $(OBJ)$/idlcmain.obj \ + $(OBJ)$/idlc.obj \ + $(OBJ)$/idlccompile.obj \ + $(OBJ)$/idlcproduce.obj \ + $(OBJ)$/errorhandler.obj \ + $(OBJ)$/options.obj \ + $(OBJ)$/fehelper.obj \ + $(OBJ)$/astdeclaration.obj \ + $(OBJ)$/astscope.obj \ + $(OBJ)$/aststack.obj \ + $(OBJ)$/astdump.obj \ + $(OBJ)$/astinterface.obj \ + $(OBJ)$/aststruct.obj \ + $(OBJ)$/aststructinstance.obj \ + $(OBJ)$/astoperation.obj \ + $(OBJ)$/astconstant.obj \ + $(OBJ)$/astenum.obj \ + $(OBJ)$/astarray.obj \ + $(OBJ)$/astunion.obj \ + $(OBJ)$/astexpression.obj \ + $(OBJ)$/astservice.obj + +APP1TARGET= $(TARGET) +APP1OBJS= $(OBJFILES) + +APP1RPATH=SDK + +APP1STDLIBS = \ + $(REGLIB) \ + $(SALLIB) \ + $(SALHELPERLIB) + +# --- Targets ------------------------------------------------------ + +.IF "$(debug)" == "" +YACCFLAGS+=-l +.ELSE +YACCFLAGS+=-v +.ENDIF + +.INCLUDE : target.mk + +$(MISC)$/stripped_scanner.ll : scanner.ll + tr -d "\015" < scanner.ll > $(MISC)$/stripped_scanner.ll + +$(MISC)$/scanner.cxx: $(MISC)$/stripped_scanner.ll + flex -o$(MISC)$/scanner.cxx $(MISC)$/stripped_scanner.ll + +$(OBJ)$/wrap_parser.obj: $(MISC)$/parser.cxx +$(OBJ)$/wrap_scanner.obj: $(MISC)$/scanner.cxx diff --git a/idlc/source/options.cxx b/idlc/source/options.cxx new file mode 100644 index 000000000000..c90bce43b3bc --- /dev/null +++ b/idlc/source/options.cxx @@ -0,0 +1,371 @@ +/************************************************************************* + * + * 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_idlc.hxx" + +#include <stdio.h> +#include /*MSVC trouble: <cstring>*/ <string.h> +#include <idlc/options.hxx> + +using namespace rtl; + +Options::Options(): m_stdin(false), m_verbose(false), m_quiet(false) +{ +} + +Options::~Options() +{ +} + +sal_Bool Options::initOptions(int ac, char* av[], sal_Bool bCmdFile) + throw( IllegalArgument ) +{ + sal_Bool ret = sal_True; + sal_uInt16 j=0; + + if (!bCmdFile) + { + bCmdFile = sal_True; + + m_program = av[0]; + + if (ac < 2) + { + fprintf(stderr, "%s", prepareHelp().getStr()); + ret = sal_False; + } + + j = 1; + } else + { + j = 0; + } + + char *s=NULL; + for (; j < ac; j++) + { + if (av[j][0] == '-') + { + switch (av[j][1]) + { + case 'O': + if (av[j][2] == '\0') + { + if (j < ac - 1 && av[j+1][0] != '-') + { + j++; + s = av[j]; + } else + { + OString tmp("'-O', please check"); + if (j <= ac - 1) + { + tmp += " your input '" + OString(av[j+1]) + "'"; + } + + throw IllegalArgument(tmp); + } + } else + { + s = av[j] + 2; + } + + m_options["-O"] = OString(s); + break; + case 'I': + { + if (av[j][2] == '\0') + { + if (j < ac - 1 && av[j+1][0] != '-') + { + j++; + s = av[j]; + } else + { + OString tmp("'-I', please check"); + if (j <= ac - 1) + { + tmp += " your input '" + OString(av[j+1]) + "'"; + } + + throw IllegalArgument(tmp); + } + } else + { + s = av[j] + 2; + } + + OString inc(s); + if ( inc.indexOf(';') > 0 ) + { + OString tmp(s); + sal_Int32 nIndex = 0; + inc = OString(); + do inc = inc + " -I\"" + tmp.getToken( 0, ';', nIndex ) +"\""; while( nIndex != -1 ); + } else + inc = OString("-I\"") + s + "\""; + + if (m_options.count("-I") > 0) + { + OString tmp(m_options["-I"]); + tmp = tmp + " " + inc; + m_options["-I"] = tmp; + } else + { + m_options["-I"] = inc; + } + } + break; + case 'D': + if (av[j][2] == '\0') + { + if (j < ac - 1 && av[j+1][0] != '-') + { + j++; + s = av[j]; + } else + { + OString tmp("'-D', please check"); + if (j <= ac - 1) + { + tmp += " your input '" + OString(av[j+1]) + "'"; + } + + throw IllegalArgument(tmp); + } + } else + { + s = av[j]; + } + + if (m_options.count("-D") > 0) + { + OString tmp(m_options["-D"]); + tmp = tmp + " " + s; + m_options["-D"] = tmp; + } else + m_options["-D"] = OString(s); + break; + case 'C': + if (av[j][2] != '\0') + { + throw IllegalArgument(OString(av[j]) + ", please check your input"); + } + if (m_options.count("-C") == 0) + m_options["-C"] = OString(av[j]); + break; + case 'c': + if (av[j][2] == 'i' && av[j][3] == 'd' && av[j][4] == '\0') + { + if (m_options.count("-cid") == 0) + m_options["-cid"] = OString(av[j]); + } else + throw IllegalArgument(OString(av[j]) + ", please check your input"); + break; + case 'v': + if ( 0 == strcmp( &av[j][1], "verbose" ) ) + { + m_verbose = true; + } + else + throw IllegalArgument(OString(av[j]) + ", please check your input"); + break; + case 'q': + if ( 0 == strcmp( &av[j][1], "quiet" ) ) + { + m_quiet = true; + } + else + throw IllegalArgument(OString(av[j]) + ", please check your input"); + break; + case 'w': + if (av[j][2] == 'e' && av[j][3] == '\0') { + if (m_options.count("-we") == 0) + m_options["-we"] = OString(av[j]); + } else { + if (av[j][2] == '\0') { + if (m_options.count("-w") == 0) + m_options["-w"] = OString(av[j]); + } else + throw IllegalArgument(OString(av[j]) + ", please check your input"); + } + break; + case 'h': + case '?': + if (av[j][2] != '\0') + { + throw IllegalArgument(OString(av[j]) + ", please check your input"); + } else + { + fprintf(stdout, "%s", prepareHelp().getStr()); + exit(0); + } + case 's': + if (/*MSVC trouble: std::*/strcmp(&av[j][2], "tdin") == 0) + { + m_stdin = true; + break; + } + // fall through + default: + throw IllegalArgument("the option is unknown" + OString(av[j])); + } + } else + { + if (av[j][0] == '@') + { + FILE* cmdFile = fopen(av[j]+1, "r"); + if( cmdFile == NULL ) + { + fprintf(stderr, "%s", prepareHelp().getStr()); + ret = sal_False; + } else + { + int rargc=0; + char* rargv[512]; + char buffer[512]=""; + + int i=0; + int found = 0; + char c; + while ( fscanf(cmdFile, "%c", &c) != EOF ) + { + if (c=='\"') { + if (found) { + found=0; + } else { + found=1; + continue; + } + } else { + if (c!=13 && c!=10) { + if (found || c!=' ') { + buffer[i++]=c; + continue; + } + } + if (i==0) + continue; + } + buffer[i]='\0'; + found=0; + i=0; + rargv[rargc]= strdup(buffer); + rargc++; + buffer[0]='\0'; + } + if (buffer[0] != '\0') { + buffer[i]='\0'; + rargv[rargc]= strdup(buffer); + rargc++; + } + fclose(cmdFile); + + ret = initOptions(rargc, rargv, bCmdFile); + + long ii = 0; + for (ii=0; ii < rargc; ii++) + { + free(rargv[ii]); + } + } + } else + { + OString name(av[j]); + name = name.toAsciiLowerCase(); + if ( name.lastIndexOf(".idl") != (name.getLength() - 4) ) + { + throw IllegalArgument("'" + OString(av[j]) + + "' is not a valid input file, only '*.idl' files will be accepted"); + } + m_inputFiles.push_back(av[j]); + } + } + } + + return ret; +} + +OString Options::prepareHelp() +{ + OString help("\nusing: "); + help += m_program + + " [-options] <file_1> ... <file_n> | @<filename> | -stdin\n"; + help += " <file_n> = file_n specifies one or more idl files.\n"; + help += " Only files with the extension '.idl' are valid.\n"; + help += " @<filename> = filename specifies the name of a command file.\n"; + help += " -stdin = read idl file from standard input.\n"; + help += " Options:\n"; + help += " -O<path> = path specifies the output directory.\n"; + help += " The generated output is a registry file with\n"; + help += " the same name as the idl input file (or 'stdin'\n"; + help += " for -stdin).\n"; + help += " -I<path> = path specifies a directory where include\n"; + help += " files will be searched by the preprocessor.\n"; + help += " Multiple directories can be combined with ';'.\n"; + help += " -D<name> = name defines a macro for the preprocessor.\n"; + help += " -C = generate complete type information, including\n"; + help += " documentation.\n"; + help += " -cid = check if identifiers fulfill the UNO naming\n"; + help += " requirements.\n"; + help += " -w = display warning messages.\n"; + help += " -we = treat warnings as errors.\n"; + help += " -h|-? = print this help message and exit.\n"; + help += prepareVersion(); + + return help; +} + +OString Options::prepareVersion() +{ + OString version("\nSun Microsystems (R) "); + version += m_program + " Version 1.1\n\n"; + return version; +} + +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."); + } +} diff --git a/idlc/source/parser.y b/idlc/source/parser.y new file mode 100644 index 000000000000..8da9c7ad63b5 --- /dev/null +++ b/idlc/source/parser.y @@ -0,0 +1,3292 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +/* + * parser.yy - BISON grammar for IDLC 1.0 + */ + +%{ +#include <string.h> + +#ifndef _IDLC_IDLC_HXX_ +#include <idlc/idlc.hxx> +#endif +#ifndef _IDLC_ERRORHANDLER_HXX_ +#include <idlc/errorhandler.hxx> +#endif +#ifndef _IDLC_FEHELPER_HXX_ +#include <idlc/fehelper.hxx> +#endif +#ifndef _IDLC_EXPRESSION_HXX_ +#include <idlc/astexpression.hxx> +#endif +#ifndef _IDLC_ASTCONSTANTS_HXX_ +#include <idlc/astconstants.hxx> +#endif +#ifndef _IDLC_ASTCONSTANT_HXX_ +#include <idlc/astconstant.hxx> +#endif +#ifndef _IDLC_ASTARRAY_HXX_ +#include <idlc/astarray.hxx> +#endif +#ifndef _IDLC_ASTBASETYPE_HXX_ +#include <idlc/astbasetype.hxx> +#endif +#ifndef _IDLC_ASTTYPEDEF_HXX_ +#include <idlc/asttypedef.hxx> +#endif +#ifndef _IDLC_ASTEXCEPTION_HXX_ +#include <idlc/astexception.hxx> +#endif +#ifndef _IDLC_ASTMEMBER_HXX_ +#include <idlc/astmember.hxx> +#endif +#ifndef _IDLC_ASTENUM_HXX_ +#include <idlc/astenum.hxx> +#endif +#ifndef _IDLC_ASTSEQUENCE_HXX_ +#include <idlc/astsequence.hxx> +#endif +#ifndef _IDLC_ASTATTRIBUTE_HXX_ +#include <idlc/astattribute.hxx> +#endif +#ifndef _IDLC_ASTOPERATION_HXX_ +#include <idlc/astoperation.hxx> +#endif +#ifndef _IDLC_ASTPARAMETER_HXX_ +#include <idlc/astparameter.hxx> +#endif +#ifndef _IDLC_ASTINTERFACEMEMBER_HXX_ +#include <idlc/astinterfacemember.hxx> +#endif +#ifndef _IDLC_ASTSERVICEMEMBER_HXX_ +#include <idlc/astservicemember.hxx> +#endif +#ifndef _IDLC_ASTOBSERVES_HXX_ +#include <idlc/astobserves.hxx> +#endif +#ifndef _IDLC_ASTNEEDS_HXX_ +#include <idlc/astneeds.hxx> +#endif +#ifndef _IDLC_ASTUNION_HXX_ +#include <idlc/astunion.hxx> +#endif +#include "idlc/aststructinstance.hxx" + +#include "attributeexceptions.hxx" + +#include "rtl/strbuf.hxx" + +#include <algorithm> +#include <vector> + +using namespace ::rtl; + +#define YYDEBUG 1 +#define YYERROR_VERBOSE 1 + +extern int yylex(void); +void yyerror(char const *); + +void checkIdentifier(::rtl::OString* id) +{ + static short check = 0; + if (check == 0) { + if (idlc()->getOptions()->isValid("-cid")) + check = 1; + else + check = 2; + } + + if ( id->indexOf('_') >= 0 ) + if ( (id->pData->buffer[0] >= 97 && id->pData->buffer[0] <= 122) + || id->pData->buffer[0] == '_') { + if (check == 1) { + ::rtl::OStringBuffer msg(25 + id->getLength()); + msg.append("mismatched identifier '"); + msg.append(*id); + msg.append("'"); + idlc()->error()->syntaxError(idlc()->getParseState(), + idlc()->getLineNumber(), + msg.getStr()); + } + else + idlc()->error()->warning0(WIDL_WRONG_NAMING_CONV, id->getStr()); + } +} + +void reportDoubleMemberDeclarations( + AstInterface::DoubleMemberDeclarations const & doubleMembers) +{ + for (AstInterface::DoubleMemberDeclarations::const_iterator i( + doubleMembers.begin()); + i != doubleMembers.end(); ++i) + { + idlc()->error()->error2(EIDL_DOUBLE_MEMBER, i->first, i->second); + } +} + +void addInheritedInterface( + AstInterface * ifc, rtl::OString const & name, bool optional, + rtl::OUString const & documentation) +{ + AstDeclaration * decl = ifc->lookupByName(name); + AstDeclaration const * resolved = resolveTypedefs(decl); + if (resolved != 0 && resolved->getNodeType() == NT_interface) { + if (idlc()->error()->checkPublished(decl)) { + if (!static_cast< AstInterface const * >(resolved)->isDefined()) { + idlc()->error()->inheritanceError( + NT_interface, &ifc->getScopedName(), decl); + } else { + AstInterface::DoubleDeclarations doubleDecls( + ifc->checkInheritedInterfaceClashes( + static_cast< AstInterface const * >(resolved), + optional)); + if (doubleDecls.interfaces.empty() + && doubleDecls.members.empty()) + { + ifc->addInheritedInterface( + static_cast< AstType * >(decl), optional, + documentation); + } else { + for (AstInterface::DoubleInterfaceDeclarations::iterator i( + doubleDecls.interfaces.begin()); + i != doubleDecls.interfaces.end(); ++i) + { + idlc()->error()->error1( + EIDL_DOUBLE_INHERITANCE, *i); + } + reportDoubleMemberDeclarations(doubleDecls.members); + } + } + } + } else { + idlc()->error()->lookupError( + EIDL_INTERFACEMEMBER_LOOKUP, name, scopeAsDecl(ifc)); + } +} + +AstDeclaration const * createNamedType( + rtl::OString const * scopedName, DeclList const * typeArgs) +{ + AstDeclaration * decl = idlc()->scopes()->topNonNull()->lookupByName( + *scopedName); + AstDeclaration const * resolved = resolveTypedefs(decl); + if (decl == 0) { + idlc()->error()->lookupError(*scopedName); + } else if (!idlc()->error()->checkPublished(decl)) { + decl = 0; + } else if (resolved->getNodeType() == NT_struct) { + if (static_cast< AstStruct const * >(resolved)->getTypeParameterCount() + != (typeArgs == 0 ? 0 : typeArgs->size())) + { + idlc()->error()->error0(EIDL_WRONG_NUMBER_OF_TYPE_ARGUMENTS); + decl = 0; + } else if (typeArgs != 0) { + AstScope * global = idlc()->scopes()->bottom(); + AstDeclaration * inst = new AstStructInstance( + static_cast< AstType * >(decl), typeArgs, global); + decl = global->addDeclaration(inst); + if (decl != inst) { + delete inst; + } + } + } else if (decl->isType()) { + if (typeArgs != 0) { + idlc()->error()->error0(EIDL_WRONG_NUMBER_OF_TYPE_ARGUMENTS); + decl = 0; + } + } else { + idlc()->error()->noTypeError(decl); + decl = 0; + } + delete scopedName; + delete typeArgs; + return decl; +} + +bool includes(AstDeclaration const * type1, AstDeclaration const * type2) { + OSL_ASSERT(type2 != 0); + if (type1 != 0) { + if (type1->getNodeType() == NT_instantiated_struct) { + AstStructInstance const * inst + = static_cast< AstStructInstance const * >(type1); + if (inst->getTypeTemplate() == type2) { + return true; + } + for (DeclList::const_iterator i(inst->getTypeArgumentsBegin()); + i != inst->getTypeArgumentsEnd(); ++i) + { + if (includes(*i, type2)) { + return true; + } + } + } else if (type1 == type2) { + return true; + } + } + return false; +} + +// Suppress any warnings from generated code: +#if defined __GNUC__ +#pragma GCC system_header +#elif defined __SUNPRO_CC +#pragma disable_warn +#elif defined _MSC_VER +#pragma warning(push, 1) +#pragma warning(disable: 4273 4701 4706) +#endif +%} +/* + * Declare the type of values in the grammar + */ +%union { + ExprType etval; /* Expression type */ + AstDeclaration* dclval; /* Declaration */ + AstDeclaration const * cdclval; + DeclList * dclsval; + AstExpression* exval; /* expression value */ + ExprList* exlval; /* expression list value */ + FeDeclarator* fdval; /* declarator value */ + FeDeclList* dlval; /* declarator list value */ + FeInheritanceHeader* ihval; /* inheritance header value */ + ::rtl::OString* sval; /* OString value */ + std::vector< rtl::OString > * svals; + sal_Char* strval; /* sal_Char* value */ + sal_Bool bval; /* sal_Boolean* value */ + sal_Int64 ival; /* sal_Int64 value */ + sal_uInt64 uval; /* sal_uInt64 value */ + sal_uInt32 ulval; /* sal_uInt32 value */ + double dval; /* double value */ + float fval; /* float value */ + StringList* slval; /* StringList value */ + LabelList* llval; /* LabelList value */ + AstUnionLabel* lbval; /* union label value */ + AstMember* mval; /* member value */ + AttributeExceptions::Part attexcpval; + AttributeExceptions attexcval; +} + +/* + * Token types: These are returned by the lexer + */ + +%token <sval> IDL_IDENTIFIER +%token IDL_ATTRIBUTE +%token IDL_BOUND +%token IDL_CASE +%token IDL_CONST +%token IDL_CONSTANTS +%token IDL_CONSTRAINED +%token IDL_DEFAULT +%token IDL_ENUM +%token IDL_EXCEPTION +%token IDL_INTERFACE +%token IDL_MAYBEAMBIGUOUS +%token IDL_MAYBEDEFAULT +%token IDL_MAYBEVOID +%token IDL_MODULE +%token IDL_NEEDS +%token IDL_OBSERVES +%token IDL_OPTIONAL +%token IDL_PROPERTY +%token IDL_RAISES +%token IDL_READONLY +%token IDL_REMOVEABLE +%token IDL_SERVICE +%token IDL_SEQUENCE +%token IDL_SINGLETON +%token IDL_STRUCT +%token IDL_SWITCH +%token IDL_TYPEDEF +%token IDL_TRANSIENT +%token IDL_UNION + +%token IDL_ANY +%token IDL_CHAR +%token IDL_BOOLEAN +%token IDL_BYTE +%token IDL_DOUBLE +%token IDL_FLOAT +%token IDL_HYPER +%token IDL_LONG +%token IDL_SHORT +%token IDL_VOID +%token IDL_STRING +%token IDL_TYPE +%token IDL_UNSIGNED + +%token IDL_TRUE +%token IDL_FALSE + +%token IDL_IN +%token IDL_OUT +%token IDL_INOUT +%token IDL_ONEWAY + +%token IDL_GET +%token IDL_SET + +%token IDL_PUBLISHED + +%token IDL_ELLIPSIS + +%token <strval> IDL_LEFTSHIFT +%token <strval> IDL_RIGHTSHIFT +%token <strval> IDL_SCOPESEPARATOR + +%token <ival> IDL_INTEGER_LITERAL +%token <uval> IDL_INTEGER_ULITERAL +%token <dval> IDL_FLOATING_PT_LITERAL + +/* + * These are production names: + */ +%type <dclval> type_dcl const_dcl +%type <dclval> array_declarator +%type <dclval> exception_name +%type <cdclval> array_type constructed_type_spec enum_type op_type_spec +%type <cdclval> sequence_type_spec simple_type_spec struct_type switch_type_spec +%type <cdclval> template_type_spec type_spec union_type +%type <cdclval> fundamental_type type_arg type_or_parameter +%type <dclsval> opt_raises raises exception_list +%type <attexcpval> opt_attribute_get_raises attribute_get_raises +%type <attexcpval> opt_attribute_set_raises attribute_set_raises +%type <dclsval> opt_type_args type_args + +%type <sval> identifier +%type <sval> interface_decl +%type <sval> scoped_name inheritance_spec +%type <slval> scoped_names at_least_one_scoped_name + +%type <etval> const_type integer_type char_type boolean_type +%type <etval> floating_pt_type any_type signed_int string_type +%type <etval> unsigned_int base_type_spec byte_type type_type + +%type <exval> expression const_expr or_expr xor_expr and_expr +%type <exval> add_expr mult_expr unary_expr primary_expr shift_expr +%type <exval> literal positive_int_expr array_dim + +%type <exlval> at_least_one_array_dim array_dims + +%type <fdval> declarator simple_declarator complex_declarator +%type <dlval> declarators at_least_one_declarator + +%type <ihval> exception_header structure_header interfaceheader + +%type <ulval> flag_header opt_attrflags opt_attrflag operation_head +%type <ulval> direction service_interface_header service_service_header + +%type <llval> case_labels at_least_one_case_label +%type <lbval> case_label +%type <mval> element_spec + +%type <bval> optional_inherited_interface opt_rest opt_service_body + +%type <attexcval> opt_attribute_block attribute_block_rest opt_attribute_raises + +%type <svals> opt_type_params type_params + +%% +/* + * Grammar start here + */ +start : definitions; + +definitions : + definition definitions + | /* EMPTY */ + ; + +definition : + opt_published publishable_definition + | module_dcl + { + idlc()->setParseState(PS_ModuleDeclSeen); + } + ';' + { + idlc()->setParseState(PS_NoState); + } + | error ';' + { + yyerror("definitions"); + yyerrok; + } + ; + +opt_published: + IDL_PUBLISHED { idlc()->setPublished(true); } + | /* empty */ { idlc()->setPublished(false); } + ; + +publishable_definition: + type_dcl + { + idlc()->setParseState(PS_TypeDeclSeen); + } + ';' + { + idlc()->setParseState(PS_NoState); + } + | const_dcl + { + idlc()->setParseState(PS_ConstantDeclSeen); + } + ';' + { + idlc()->setParseState(PS_NoState); + } + | exception_dcl + { + idlc()->setParseState(PS_ExceptionDeclSeen); + } + ';' + { + idlc()->setParseState(PS_NoState); + } + | interface + { + idlc()->setParseState(PS_InterfaceDeclSeen); + } + ';' + { + idlc()->setParseState(PS_NoState); + } + | service_dcl + { + idlc()->setParseState(PS_ServiceDeclSeen); + } + ';' + { + idlc()->setParseState(PS_NoState); + } + | singleton_dcl + { + idlc()->setParseState(PS_SingletonDeclSeen); + } + ';' + { + idlc()->setParseState(PS_NoState); + } + | constants_dcl + { + idlc()->setParseState(PS_ConstantsDeclSeen); + } + ';' + { + idlc()->setParseState(PS_NoState); + } + ; + +module_dcl : + IDL_MODULE + { + idlc()->setParseState(PS_ModuleSeen); + idlc()->setPublished(false); + } + identifier + { + idlc()->setParseState(PS_ModuleIDSeen); + checkIdentifier($3); + + AstScope* pScope = idlc()->scopes()->topNonNull(); + AstModule* pModule = NULL; + AstDeclaration* pExists = NULL; + + if ( pScope ) + { + pModule = new AstModule(*$3, pScope); + if( (pExists = pScope->lookupForAdd(pModule)) ) + { + pExists->setInMainfile(idlc()->isInMainFile()); + pExists->setFileName(pModule->getFileName()); + if (pExists->isPredefined()) + { + pExists->setPredefined(false); + if (pExists->getDocumentation().getLength() == 0 && + pModule->getDocumentation().getLength() > 0) + { + pExists->setDocumentation(pModule->getDocumentation()); + } + } + delete(pModule); + pModule = (AstModule*)pExists; + } else + { + pScope->addDeclaration(pModule); + } + idlc()->scopes()->push(pModule); + } + delete $3; + } + '{' + { + idlc()->setParseState(PS_ModuleSqSeen); + } + definitions + { + idlc()->setParseState(PS_ModuleBodySeen); + } + '}' + { + idlc()->setParseState(PS_ModuleQsSeen); + /* + * Finished with this module - pop it from the scope stack + */ + idlc()->scopes()->pop(); + } + ; + +interface : + interface_dcl + | forward_dcl + ; + +interface_decl : + IDL_INTERFACE + { + idlc()->setParseState(PS_InterfaceSeen); + } + identifier + { + idlc()->setParseState(PS_InterfaceIDSeen); + checkIdentifier($3); + $$ = $3; + } + ; + +forward_dcl : + interface_decl + { + idlc()->setParseState(PS_ForwardDeclSeen); + + AstScope* pScope = idlc()->scopes()->topNonNull(); + AstInterface* pForward = NULL; + AstDeclaration* pDecl = NULL; + + /* + * Make a new forward interface node and add it to its enclosing scope + */ + if ( pScope && $1 ) + { + pForward = new AstInterface(*$1, NULL, pScope); + + if ( pDecl = pScope->lookupByName(pForward->getScopedName()) ) + { + if ( (pDecl != pForward) && + (pDecl->getNodeType() == NT_interface) ) + { + delete pForward; + } else + { + idlc()->error()->error2(EIDL_REDEF_SCOPE, scopeAsDecl(pScope), pDecl); + } + } else + { + /* + * Add the interface to its definition scope + */ + pScope->addDeclaration(pForward); + } + } + delete $1; + } + ; + +interface_dcl : + interfaceheader + { + idlc()->setParseState(PS_InterfaceHeadSeen); + + AstScope* pScope = idlc()->scopes()->topNonNull(); + AstInterface* pInterface = NULL; + AstInterface* pForward = NULL; + AstDeclaration* pDecl = NULL; + + /* + * Make a new interface node and add it to its enclosing scope + */ + if ( pScope && $1 ) + { + pInterface = new AstInterface( + *$1->getName(), + static_cast< AstInterface * >($1->getInherits()), pScope); + if ( pInterface && + (pDecl = pScope->lookupByName(pInterface->getScopedName())) ) + { + /* + * See if we're defining a forward declared interface. + */ + if (pDecl->getNodeType() == NT_interface) + { + pForward = (AstInterface*)pDecl; + if ( !pForward->isDefined() ) + { + /* + * Check if redefining in same scope + */ + if ( pForward->getScope() != pScope ) + { + if ( pForward->getScopedName() != pInterface->getScopedName() ) + { + idlc()->error()->error3(EIDL_SCOPE_CONFLICT, + pInterface, pForward, scopeAsDecl(pScope)); + } + } + else if ( !pInterface->isPublished() + && pForward->isPublished() ) + { + idlc()->error()->error0(EIDL_PUBLISHED_FORWARD); + } + /* + * All OK, set full definition + */ + else + { + pForward->forwardDefined(*pInterface); + delete pInterface; + pInterface = pForward; + } + } else { + // special handling for XInterface because it is predefined + if ( pForward->isPredefined() && + pForward->getScopedName() == "com::sun::star::uno::XInterface") + { + /* replace the predefined XInterface */ + *pForward = *pInterface; + delete pInterface; + pInterface = pForward; + } + + } + } + } else + { + /* + * Add the interface to its definition scope + */ + pScope->addDeclaration(pInterface); + } + } + /* + * Push it on the scope stack + */ + idlc()->scopes()->push(pInterface); + delete($1); + } + '{' + { + idlc()->setParseState(PS_InterfaceSqSeen); + } + exports + { + AstInterface * ifc = static_cast< AstInterface * >( + idlc()->scopes()->topNonNull()); + if (!ifc->hasMandatoryInheritedInterfaces() + && ifc->getScopedName() != "com::sun::star::uno::XInterface") + { + addInheritedInterface( + ifc, rtl::OString("::com::sun::star::uno::XInterface"), false, + rtl::OUString()); + } + ifc->setDefined(); + idlc()->setParseState(PS_InterfaceBodySeen); + } + '}' + { + idlc()->setParseState(PS_InterfaceQsSeen); + /* + * Done with this interface - pop it off the scopes stack + */ + idlc()->scopes()->pop(); + } + | error '}' + { + yyerror("interface definition"); + yyerrok; + } + ; + +interfaceheader : + interface_decl inheritance_spec + { + idlc()->setParseState(PS_InheritSpecSeen); + + $$ = new FeInheritanceHeader(NT_interface, $1, $2, 0); + delete $2; + } + ; + +inheritance_spec : + ':' + { + idlc()->setParseState(PS_InheritColonSeen); + } + scoped_name + { + $$ = $3; + } + | /* EMPTY */ + { + $$ = NULL; + } + ; + +exports : + exports export + | /* EMPTY */ + ; + +export : + attribute + { + idlc()->setParseState(PS_AttributeDeclSeen); + } + ';' + { + idlc()->setParseState(PS_NoState); + } + | operation + { + idlc()->setParseState(PS_OperationDeclSeen); + } + ';' + { + idlc()->setParseState(PS_NoState); + } + | interface_inheritance_decl + { + idlc()->setParseState(PS_InterfaceInheritanceDeclSeen); + } + ';' + { + idlc()->setParseState(PS_NoState); + } + ; + +attribute : + flag_header + simple_type_spec + { + idlc()->setParseState(PS_AttrTypeSeen); + } + simple_declarator + { + idlc()->setParseState(PS_AttrCompleted); + if (($1 & ~(AF_BOUND | AF_READONLY)) != AF_ATTRIBUTE) { + idlc()->error()->flagError(EIDL_BAD_ATTRIBUTE_FLAGS, $1); + } + AstInterface * scope = static_cast< AstInterface * >( + idlc()->scopes()->top()); + AstAttribute * attr = new AstAttribute( + $1, $4->compose($2), $4->getName(), scope); + delete $4; + AstInterface::DoubleMemberDeclarations doubleMembers( + scope->checkMemberClashes(attr)); + if (doubleMembers.empty()) { + scope->addMember(attr); + } else { + reportDoubleMemberDeclarations(doubleMembers); + } + idlc()->scopes()->push(attr); + } + opt_attribute_block + { + static_cast< AstAttribute * >(idlc()->scopes()->top())->setExceptions( + $6.get.documentation, $6.get.exceptions, $6.set.documentation, + $6.set.exceptions); + delete $6.get.documentation; + delete $6.get.exceptions; + delete $6.set.documentation; + delete $6.set.exceptions; + idlc()->scopes()->pop(); + } + ; + +flag_header : + '[' opt_attrflags ']' + { + idlc()->setParseState(PS_FlagHeaderSeen); + $$ = $2; + } + ; + +opt_attrflags : + opt_attrflags ',' opt_attrflag + { + if ( ($1 & $3) == $3 ) + idlc()->error()->flagError(EIDL_DEFINED_ATTRIBUTEFLAG, $3); + + $$ = $1 | $3; + } + | opt_attrflag + { + $$ = $1; + } + ; + +opt_attrflag : + IDL_ATTRIBUTE + { + idlc()->setParseState(PS_AttrSeen); + $$ = AF_ATTRIBUTE; + } + | IDL_PROPERTY + { + idlc()->setParseState(PS_PropertySeen); + $$ = AF_PROPERTY; + } + | IDL_READONLY + { + idlc()->setParseState(PS_ReadOnlySeen); + $$ = AF_READONLY; + } + | IDL_OPTIONAL + { + idlc()->setParseState(PS_OptionalSeen); + $$ = AF_OPTIONAL; + } + | IDL_MAYBEVOID + { + idlc()->setParseState(PS_MayBeVoidSeen); + $$ = AF_MAYBEVOID; + } + | IDL_BOUND + { + idlc()->setParseState(PS_BoundSeen); + $$ = AF_BOUND; + } + | IDL_CONSTRAINED + { + idlc()->setParseState(PS_ConstrainedSeen); + $$ = AF_CONSTRAINED; + } + | IDL_TRANSIENT + { + idlc()->setParseState(PS_TransientSeen); + $$ = AF_TRANSIENT; + } + | IDL_MAYBEAMBIGUOUS + { + idlc()->setParseState(PS_MayBeAmbigiousSeen); + $$ = AF_MAYBEAMBIGUOUS; + } + | IDL_MAYBEDEFAULT + { + idlc()->setParseState(PS_MayBeDefaultSeen); + $$ = AF_MAYBEDEFAULT; + } + | IDL_REMOVEABLE + { + idlc()->setParseState(PS_RemoveableSeen); + $$ = AF_REMOVEABLE; + } + | error ']' + { + yyerror("unknown property|attribute flag"); + yyerrok; + } + ; + +opt_attribute_block: + '{' attribute_block_rest { $$ = $2; } + | /* empty */ + { + $$.get.documentation = 0; + $$.get.exceptions = 0; + $$.set.documentation = 0; + $$.set.exceptions = 0; + } + ; + +attribute_block_rest: + opt_attribute_raises '}' + | error '}' + { + yyerror("bad attribute raises block"); + yyerrok; + $$.get.documentation = 0; + $$.get.exceptions = 0; + $$.set.documentation = 0; + $$.set.exceptions = 0; + } + ; + +opt_attribute_raises: + attribute_get_raises + opt_attribute_set_raises + { + $$.get = $1; + $$.set = $2; + } + | attribute_set_raises + opt_attribute_get_raises + { + $$.get = $2; + $$.set = $1; + } + | /* empty */ + { + $$.get.documentation = 0; + $$.get.exceptions = 0; + $$.set.documentation = 0; + $$.set.exceptions = 0; + } + ; + +opt_attribute_get_raises: + attribute_get_raises + | /* empty */ { $$.documentation = 0; $$.exceptions = 0; } + ; + +attribute_get_raises: + IDL_GET raises ';' + { + $$.documentation = new rtl::OUString( + rtl::OStringToOUString( + idlc()->getDocumentation(), RTL_TEXTENCODING_UTF8)); + $$.exceptions = $2; + } + ; + +opt_attribute_set_raises: + attribute_set_raises + | /* empty */ { $$.documentation = 0; $$.exceptions = 0; } + ; + +attribute_set_raises: + IDL_SET + { + if (static_cast< AstAttribute * >(idlc()->scopes()->top())-> + isReadonly()) + { + idlc()->error()->error0(EIDL_READONLY_ATTRIBUTE_SET_EXCEPTIONS); + } + } + raises ';' + { + $$.documentation = new rtl::OUString( + rtl::OStringToOUString( + idlc()->getDocumentation(), RTL_TEXTENCODING_UTF8)); + $$.exceptions = $3; + } + ; + +operation : + operation_head + op_type_spec + { + idlc()->setParseState(PS_OpTypeSeen); + } + identifier + { + idlc()->setParseState(PS_OpIDSeen); + checkIdentifier($4); + + AstInterface * pScope = static_cast< AstInterface * >( + idlc()->scopes()->top()); + AstOperation* pOp = NULL; + + /* + * Create a node representing an operation on an interface + * and add it to its enclosing scope + */ + if ( pScope && $2 ) + { + AstType *pType = (AstType*)$2; + if ( !pType || (pType->getNodeType() == NT_exception) ) + { + // type ERROR + } else + { + pOp = new AstOperation($1, pType, *$4, pScope); + + AstInterface::DoubleMemberDeclarations doubleMembers( + pScope->checkMemberClashes(pOp)); + if (doubleMembers.empty()) { + pScope->addMember(pOp); + } else { + reportDoubleMemberDeclarations(doubleMembers); + } + } + } + delete $4; + /* + * Push the operation scope onto the scopes stack + */ + idlc()->scopes()->push(pOp); + } + '(' + { + idlc()->setParseState(PS_OpSqSeen); + } + parameters + { + idlc()->setParseState(PS_OpParsCompleted); + } + ')' + { + idlc()->setParseState(PS_OpQsSeen); + } + opt_raises + { + AstScope* pScope = idlc()->scopes()->topNonNull(); + AstOperation* pOp = NULL; + /* + * Add exceptions and context to the operation + */ + if ( pScope && pScope->getScopeNodeType() == NT_operation) + { + pOp = (AstOperation*)pScope; + + if ( pOp ) + pOp->setExceptions($12); + } + delete $12; + /* + * Done with this operation. Pop its scope from the scopes stack + */ + idlc()->scopes()->pop(); + } + ; + +operation_head : + '[' + IDL_ONEWAY + { + idlc()->setParseState(PS_OpOnewaySeen); + } + ']' + { + idlc()->setParseState(PS_OpHeadSeen); + $$ = OP_ONEWAY; + } + | /* EMPTY */ + { + $$ = OP_NONE; + } + ; + +op_type_spec : + simple_type_spec + | IDL_VOID + { + $$ = idlc()->scopes()->bottom()->lookupPrimitiveType(ET_void); + } + ; + +parameters : + parameter + | parameters + ',' + { + idlc()->setParseState(PS_OpParCommaSeen); + } + parameter + | /* EMPTY */ + | error ',' + { + yyerror("parameter definition"); + yyerrok; + } + ; + +parameter : + '[' + direction + ']' + { + idlc()->setParseState(PS_OpParDirSeen); + } + simple_type_spec + { + idlc()->setParseState(PS_OpParTypeSeen); + } + opt_rest + declarator + { + idlc()->setParseState(PS_OpParDeclSeen); + + AstOperation * pScope = static_cast< AstOperation * >( + idlc()->scopes()->top()); + AstParameter* pParam = NULL; + + /* + * Create a node representing an argument to an operation + * Add it to the enclosing scope (the operation scope) + */ + if ( pScope && $5 && $8 ) + { + AstType const * pType = $8->compose($5); + if ( pType ) + { + if (pScope->isConstructor() && $2 != DIR_IN) { + idlc()->error()->error0(EIDL_CONSTRUCTOR_PARAMETER_NOT_IN); + } + if (pScope->isVariadic()) { + idlc()->error()->error0(EIDL_REST_PARAMETER_NOT_LAST); + } + if ($7) { + AstDeclaration const * type = resolveTypedefs(pType); + if (type->getNodeType() != NT_predefined + || (static_cast< AstBaseType const * >(type)-> + getExprType() != ET_any)) + { + idlc()->error()->error0(EIDL_REST_PARAMETER_NOT_ANY); + } + if (pScope->isConstructor()) { + if (pScope->getIteratorBegin() + != pScope->getIteratorEnd()) + { + idlc()->error()->error0( + EIDL_CONSTRUCTOR_REST_PARAMETER_NOT_FIRST); + } + } else { + idlc()->error()->error0(EIDL_METHOD_HAS_REST_PARAMETER); + } + } + + pParam = new AstParameter( + static_cast< Direction >($2), $7, pType, $8->getName(), + pScope); + + if ( !$8->checkType($5) ) + { + // WARNING + } + + pScope->addDeclaration(pParam); + } + } + } + | error + simple_type_spec + { + idlc()->setParseState(PS_NoState); + yyerrok; + } + ; + +direction : + IDL_IN + { + $$ = DIR_IN; + } + | IDL_OUT + { + $$ = DIR_OUT; + } + | IDL_INOUT + { + $$ = DIR_INOUT; + } + ; + +opt_rest: + IDL_ELLIPSIS + { + $$ = true; + } + | /* empty */ + { + $$ = false; + } + ; + +opt_raises: + raises + | /* empty */ + { + $$ = 0; + } + ; + +raises: + IDL_RAISES + { + idlc()->setParseState(PS_RaiseSeen); + } + '(' + { + idlc()->setParseState(PS_RaiseSqSeen); + } + exception_list + ')' + { + idlc()->setParseState(PS_RaiseQsSeen); + $$ = $5; + } + ; + +exception_list: + exception_name + { + $$ = new DeclList; + $$->push_back($1); + } + | exception_list ',' exception_name + { + $1->push_back($3); + $$ = $1; + } + ; + +exception_name: + scoped_name + { + // The topmost scope is either an AstOperation (for interface methods + // and service constructors) or an AstAttribute (for interface + // attributes), so look up exception names in the next-to-topmost scope: + AstDeclaration * decl = idlc()->scopes()->nextToTop()->lookupByName( + *$1); + if (decl == 0) { + idlc()->error()->lookupError(*$1); + } else if (!idlc()->error()->checkPublished(decl)) { + decl = 0; + } else if (decl->getNodeType() != NT_exception) { + idlc()->error()->error1(EIDL_ILLEGAL_RAISES, decl); + decl = 0; + } + delete $1; + $$ = decl; + } + ; + +interface_inheritance_decl: + optional_inherited_interface + IDL_INTERFACE + { + idlc()->setParseState(PS_ServiceIFHeadSeen); + } + scoped_name + { + AstInterface * ifc = static_cast< AstInterface * >( + idlc()->scopes()->top()); + if (ifc->usesSingleInheritance()) { + idlc()->error()->error0(EIDL_MIXED_INHERITANCE); + } else { + addInheritedInterface( + ifc, *$4, $1, + rtl::OStringToOUString( + idlc()->getDocumentation(), RTL_TEXTENCODING_UTF8)); + } + delete $4; + } + ; + +optional_inherited_interface: + '[' IDL_OPTIONAL ']' { $$ = true; } + | /* EMPTY */ { $$ = false; } + ; + +constants_exports : + constants_export constants_exports + | /* EMPTY */ + ; + +constants_export : + const_dcl + { + idlc()->setParseState(PS_ConstantDeclSeen); + } + ';' {}; + +const_dcl : + IDL_CONST + { + idlc()->setParseState(PS_ConstSeen); + } + const_type + { + idlc()->setParseState(PS_ConstTypeSeen); + } + identifier + { + idlc()->setParseState(PS_ConstIDSeen); + checkIdentifier($5); + } + '=' + { + idlc()->setParseState(PS_ConstAssignSeen); + } + expression + { + idlc()->setParseState(PS_ConstExprSeen); + + AstScope* pScope = idlc()->scopes()->topNonNull(); + AstConstant* pConstant = NULL; + + if ( $9 && pScope ) + { + if ( !$9->coerce($3) ) + { + idlc()->error()->coercionError($9, $3); + } else + { + pConstant = new AstConstant($3, $9, *$5, pScope); + pScope->addDeclaration(pConstant); + } + } + delete $5; + } + ; + +constants_dcl : + IDL_CONSTANTS + { + idlc()->setParseState(PS_ConstantsSeen); + } + identifier + { + idlc()->setParseState(PS_ConstantsIDSeen); + checkIdentifier($3); + } + '{' + { + idlc()->setParseState(PS_ConstantsSqSeen); + + AstScope* pScope = idlc()->scopes()->topNonNull(); + AstConstants* pConstants = NULL; + AstDeclaration* pExists = NULL; + + if ( pScope ) + { + pConstants = new AstConstants(*$3, pScope); + if( (pExists = pScope->lookupForAdd(pConstants)) ) + { + pExists->setInMainfile(idlc()->isInMainFile()); + delete(pConstants); + pConstants = (AstConstants*)pExists; + } else + { + pScope->addDeclaration(pConstants); + } + idlc()->scopes()->push(pConstants); + } + delete $3; + } + constants_exports + { + idlc()->setParseState(PS_ConstantsBodySeen); + } + '}' + { + idlc()->setParseState(PS_ConstantsQsSeen); + /* + * Finished with this constants - pop it from the scope stack + */ + idlc()->scopes()->pop(); + } + ; + +expression : const_expr ; + +const_expr : or_expr ; + +or_expr : + xor_expr + | or_expr '|' xor_expr + { + $$ = new AstExpression(EC_or, $1, $3); + } + ; + +xor_expr : + and_expr + | xor_expr '^' and_expr + { + $$ = new AstExpression(EC_xor, $1, $3); + } + ; + +and_expr : + shift_expr + | and_expr '&' shift_expr + { + $$ = new AstExpression(EC_and, $1, $3); + } + ; + +shift_expr : + add_expr + | shift_expr IDL_LEFTSHIFT add_expr + { + $$ = new AstExpression(EC_left, $1, $3); + } + | shift_expr IDL_RIGHTSHIFT add_expr + { + $$ = new AstExpression(EC_right, $1, $3); + } + ; + +add_expr : + mult_expr + | add_expr '+' mult_expr + { + $$ = new AstExpression(EC_add, $1, $3); + } + | add_expr '-' mult_expr + { + $$ = new AstExpression(EC_minus, $1, $3); + } + ; + +mult_expr : + unary_expr + | mult_expr '*' unary_expr + { + $$ = new AstExpression(EC_mul, $1, $3); + } + | mult_expr '/' unary_expr + { + $$ = new AstExpression(EC_div, $1, $3); + } + | mult_expr '%' unary_expr + { + $$ = new AstExpression(EC_mod, $1, $3); + } + ; + +unary_expr : + primary_expr + | '+' primary_expr + { + $$ = new AstExpression(EC_u_plus, $2, NULL); + } + | '-' primary_expr + { + $$ = new AstExpression(EC_u_minus, $2, NULL); + } + | '~' primary_expr + { + } + ; + +primary_expr : + scoped_name + { + /* + * An expression which is a scoped name is not resolved now, + * but only when it is evaluated (such as when it is assigned + * as a constant value) + */ + $$ = new AstExpression($1); + } + | literal + | '(' const_expr ')' + { + $$ = $2; + } + ; + +literal : + IDL_INTEGER_LITERAL + { + $$ = new AstExpression($1); + } + | IDL_INTEGER_ULITERAL + { + $$ = new AstExpression($1); + } + | IDL_FLOATING_PT_LITERAL + { + $$ = new AstExpression($1); + } + | IDL_TRUE + { + $$ = new AstExpression((sal_Int32)1, ET_boolean); + } + | IDL_FALSE + { + $$ = new AstExpression((sal_Int32)0, ET_boolean); + } + ; + +positive_int_expr : + const_expr + { + $1->evaluate(EK_const); + if ( !$1->coerce(ET_ulong) ) + { + idlc()->error()->coercionError($1, ET_ulong); + delete $1; + $$ = NULL; + } + } + ; + +const_type : + integer_type + | char_type + | byte_type + | boolean_type + | floating_pt_type + | scoped_name + { + AstScope* pScope = idlc()->scopes()->topNonNull(); + AstDeclaration const * type = 0; + + /* + * If the constant's type is a scoped name, it must resolve + * to a scalar constant type + */ + if ( pScope && (type = pScope->lookupByName(*$1)) ) { + if (!idlc()->error()->checkPublished(type)) + { + type = 0; + } + else + { + type = resolveTypedefs(type); + if (type->getNodeType() == NT_predefined) + { + $$ = static_cast< AstBaseType const * >(type)-> + getExprType(); + } else + $$ = ET_any; + } + } else + $$ = ET_any; + } + ; + +exception_header : + IDL_EXCEPTION + { + idlc()->setParseState(PS_ExceptSeen); + } + identifier + { + idlc()->setParseState(PS_ExceptIDSeen); + checkIdentifier($3); + } + inheritance_spec + { + idlc()->setParseState(PS_InheritSpecSeen); + + $$ = new FeInheritanceHeader(NT_exception, $3, $5, 0); + delete $5; + } + ; + +exception_dcl : + exception_header + { + idlc()->setParseState(PS_ExceptHeaderSeen); + + AstScope* pScope = idlc()->scopes()->topNonNull(); + AstException* pExcept = NULL; + + if ( pScope ) + { + AstException* pBase = static_cast< AstException* >( + $1->getInherits()); + pExcept = new AstException(*$1->getName(), pBase, pScope); + pScope->addDeclaration(pExcept); + } + /* + * Push the scope of the exception on the scopes stack + */ + idlc()->scopes()->push(pExcept); + delete $1; + } + '{' + { + idlc()->setParseState(PS_ExceptSqSeen); + } + members + { + idlc()->setParseState(PS_ExceptBodySeen); + } + '}' + { + idlc()->setParseState(PS_ExceptQsSeen); + /* this exception is finished, pop its scope from the stack */ + idlc()->scopes()->pop(); + } + ; + +property : + flag_header + simple_type_spec + { + idlc()->setParseState(PS_PropertyTypeSeen); + } + at_least_one_declarator + { + idlc()->setParseState(PS_PropertyCompleted); + + AstScope* pScope = idlc()->scopes()->topNonNull(); + AstAttribute* pAttr = NULL; + FeDeclList* pList = $4; + FeDeclarator* pDecl = NULL; + AstType const * pType = NULL; + + if ( pScope->getScopeNodeType() == NT_singleton ) + { + idlc()->error()->error0(EIDL_ILLEGAL_ADD); + } else + { + if ( ($1 & AF_ATTRIBUTE) == AF_ATTRIBUTE ) + idlc()->error()->flagError(EIDL_WRONGATTRIBUTEKEYWORD, AF_ATTRIBUTE); + + if ( ($1 & AF_PROPERTY) != AF_PROPERTY ) + idlc()->error()->flagError(EIDL_MISSINGATTRIBUTEKEYWORD, AF_PROPERTY); + + /* + * Create nodes representing attributes and add them to the + * enclosing scope + */ + if ( pScope && $2 && pList ) + { + FeDeclList::iterator iter = pList->begin(); + FeDeclList::iterator end = pList->end(); + + while (iter != end) + { + pDecl = (*iter); + if ( !pDecl ) + { + iter++; + continue; + } + + pType = pDecl->compose($2); + + if ( !pType ) + { + iter++; + continue; + } + + pAttr = new AstAttribute(NT_property, $1, pType, pDecl->getName(), pScope); + + pScope->addDeclaration(pAttr); + iter++; + delete pDecl; + } + } + } + + if ( pList ) + delete pList; + } + | error ';' + { + yyerror("property"); + yyerrok; + } + ; + +service_exports : + service_exports service_export + | /* EMPTY */ + ; + +service_export : + service_interface_header + at_least_one_scoped_name + ';' + { + idlc()->setParseState(PS_ServiceMemberSeen); + + AstScope* pScope = idlc()->scopes()->topNonNull(); + AstDeclaration* pDecl = NULL; + AstInterfaceMember* pIMember = NULL; + + if ( pScope->getScopeNodeType() == NT_singleton ) + { + idlc()->error()->error0(EIDL_ILLEGAL_ADD); + } else + { + /* + * Create a node representing a class member. + * Store it in the enclosing scope + */ + if ( pScope && $2 ) + { + StringList::iterator iter = $2->begin(); + StringList::iterator end = $2->end(); + + while ( iter != end ) + { + pDecl = pScope->lookupByName(*iter); + if ( pDecl && (pDecl->getNodeType() == NT_interface) ) + { + /* we relax the strict published check and allow to add new + * interfaces if they are optional + */ + bool bOptional = (($1 & AF_OPTIONAL) == AF_OPTIONAL); + if ( idlc()->error()->checkPublished(pDecl, bOptional) ) + { + pIMember = new AstInterfaceMember( + $1, (AstInterface*)pDecl, *iter, pScope); + pScope->addDeclaration(pIMember); + } + } else + { + idlc()->error()-> + lookupError(EIDL_INTERFACEMEMBER_LOOKUP, *iter, scopeAsDecl(pScope)); + } + iter++; + } + } + } + delete $2; + } + | service_service_header + at_least_one_scoped_name + ';' + { + idlc()->setParseState(PS_ServiceMemberSeen); + + AstScope* pScope = idlc()->scopes()->topNonNull(); + AstDeclaration* pDecl = NULL; + AstServiceMember* pSMember = NULL; + + /* + * Create a node representing a class member. + * Store it in the enclosing scope + */ + if ( pScope && $2 ) + { + StringList::iterator iter = $2->begin(); + StringList::iterator end = $2->end(); + + while ( iter != end ) + { + pDecl = pScope->lookupByName(*iter); + if ( pDecl && (pDecl->getNodeType() == NT_service) ) + { + if ( pScope->getScopeNodeType() == NT_singleton && pScope->nMembers() > 0 ) + idlc()->error()->error0(EIDL_ILLEGAL_ADD); + else if ( idlc()->error()->checkPublished(pDecl) ) + { + pSMember = new AstServiceMember( + $1, (AstService*)pDecl, *iter, pScope); + pScope->addDeclaration(pSMember); + } + } else + { + idlc()->error()-> + lookupError(EIDL_SERVICEMEMBER_LOOKUP, *iter, scopeAsDecl(pScope)); + } + iter++; + } + } + delete $2; + } + | IDL_OBSERVES + at_least_one_scoped_name + ';' + { + idlc()->setParseState(PS_ServiceMemberSeen); + + AstScope* pScope = idlc()->scopes()->topNonNull(); + AstDeclaration* pDecl = NULL; + AstObserves* pObserves = NULL; + + if ( pScope->getScopeNodeType() == NT_singleton ) + { + idlc()->error()->error0(EIDL_ILLEGAL_ADD); + } else + { + /* + * Create a node representing a class member. + * Store it in the enclosing scope + */ + if ( pScope && $2 ) + { + StringList::iterator iter = $2->begin(); + StringList::iterator end = $2->end(); + + while ( iter != end ) + { + pDecl = pScope->lookupByName(*iter); + if ( pDecl && (pDecl->getNodeType() == NT_interface) ) + { + pObserves = new AstObserves((AstInterface*)pDecl, *iter, pScope); + pScope->addDeclaration(pObserves); + } else + { + idlc()->error()-> + lookupError(EIDL_INTERFACEMEMBER_LOOKUP, *iter, scopeAsDecl(pScope)); + } + iter++; + } + } + } + delete $2; + } + | IDL_NEEDS + at_least_one_scoped_name + ';' + { + idlc()->setParseState(PS_ServiceMemberSeen); + + AstScope* pScope = idlc()->scopes()->topNonNull(); + AstDeclaration* pDecl = NULL; + AstNeeds* pNeeds = NULL; + + if ( pScope->getScopeNodeType() == NT_singleton ) + { + idlc()->error()->error0(EIDL_ILLEGAL_ADD); + } else + { + /* + * Create a node representing a class member. + * Store it in the enclosing scope + */ + if ( pScope && $2 ) + { + StringList::iterator iter = $2->begin(); + StringList::iterator end = $2->end(); + + while ( iter != end ) + { + pDecl = pScope->lookupByName(*iter); + if ( pDecl && (pDecl->getNodeType() == NT_service) ) + { + pNeeds = new AstNeeds((AstService*)pDecl, *iter, pScope); + pScope->addDeclaration(pNeeds); + } else + { + idlc()->error()-> + lookupError(EIDL_SERVICEMEMBER_LOOKUP, *iter, scopeAsDecl(pScope)); + } + iter++; + } + } + } + delete $2; + } + | property + ';' + { + idlc()->setParseState(PS_PropertyDeclSeen); + } + ; + +service_interface_header : + IDL_INTERFACE + { + idlc()->setParseState(PS_ServiceIFHeadSeen); + $$ = AF_INVALID; + } + | flag_header + IDL_INTERFACE + { + idlc()->setParseState(PS_ServiceIFHeadSeen); + if ( (AF_OPTIONAL != $1) && ( AF_INVALID != $1) ) + idlc()->error()->flagError(EIDL_OPTIONALEXPECTED, $1); + $$ = $1; + } + ; + +service_service_header : + IDL_SERVICE + { + idlc()->setParseState(PS_ServiceSHeadSeen); + $$ = AF_INVALID; + } + | flag_header + IDL_SERVICE + { + idlc()->setParseState(PS_ServiceSHeadSeen); + if ( (AF_OPTIONAL != $1) && ( AF_INVALID != $1) ) + idlc()->error()->flagError(EIDL_OPTIONALEXPECTED, $1); + $$ = $1; + } + ; + +service_dcl : + IDL_SERVICE + { + idlc()->setParseState(PS_ServiceSeen); + } + identifier + { + idlc()->setParseState(PS_ServiceIDSeen); + checkIdentifier($3); + + AstScope* pScope = idlc()->scopes()->topNonNull(); + AstService* pService = NULL; + + /* + * Make a new service and add it to the enclosing scope + */ + if (pScope != NULL) + { + pService = new AstService(*$3, pScope); + pScope->addDeclaration(pService); + } + delete $3; + /* + * Push it on the stack + */ + idlc()->scopes()->push(pService); + } + service_dfn + { + /* this service is finished, pop its scope from the stack */ + idlc()->scopes()->pop(); + } + ; + +service_dfn: + service_interface_dfn + | service_obsolete_dfn + ; + +service_interface_dfn: + ':' scoped_name + { + AstScope * scope = idlc()->scopes()->nextToTop(); + // skip the scope pushed by service_dcl + AstDeclaration * decl = scope->lookupByName(*$2); + if (decl != 0 && resolveTypedefs(decl)->getNodeType() == NT_interface) { + if (idlc()->error()->checkPublished(decl)) { + idlc()->scopes()->top()->addDeclaration(decl); + } + } else { + idlc()->error()->lookupError( + EIDL_INTERFACEMEMBER_LOOKUP, *$2, scopeAsDecl(scope)); + } + delete $2; + } + opt_service_body + { + AstService * s = static_cast< AstService * >(idlc()->scopes()->top()); + if (s != 0) { + s->setDefaultConstructor(!$4); + } + } + ; + +opt_service_body: + service_body { $$ = true; } + | /* empty */ { $$ = false; } + ; + +service_body: + '{' + constructors + '}' + ; + +constructors: + constructors constructor + | /* empty */ + ; + +constructor: + identifier + { + checkIdentifier($1); + AstScope * scope = idlc()->scopes()->top(); + AstOperation * ctor = new AstOperation(OP_NONE, 0, *$1, scope); + delete $1; + scope->addDeclaration(ctor); + idlc()->scopes()->push(ctor); + } + '(' + parameters + ')' + opt_raises + { + static_cast< AstOperation * >(idlc()->scopes()->top())->setExceptions( + $6); + delete $6; + idlc()->scopes()->pop(); + if (static_cast< AstService * >(idlc()->scopes()->top())-> + checkLastConstructor()) + { + idlc()->error()->error0(EIDL_SIMILAR_CONSTRUCTORS); + } + } + ';' + ; + +singleton_dcl : + IDL_SINGLETON + { + idlc()->setParseState(PS_SingletonSeen); + } + identifier + { + idlc()->setParseState(PS_SingletonIDSeen); + checkIdentifier($3); + + AstScope* pScope = idlc()->scopes()->topNonNull(); + AstService* pService = NULL; + + /* + * Make a new service and add it to the enclosing scope + */ + if (pScope != NULL) + { + pService = new AstService(NT_singleton, *$3, pScope); + pScope->addDeclaration(pService); + } + delete $3; + /* + * Push it on the stack + */ + idlc()->scopes()->push(pService); + } + singleton_dfn + { + /* this singelton is finished, pop its scope from the stack */ + idlc()->scopes()->pop(); + } + ; + +singleton_dfn: + singleton_interface_dfn + | service_obsolete_dfn + ; + +singleton_interface_dfn: + ':' scoped_name + { + AstScope * scope = idlc()->scopes()->nextToTop(); + // skip the scope (needlessly) pushed by singleton_dcl + AstDeclaration * decl = scope->lookupByName(*$2); + if (decl != 0 && resolveTypedefs(decl)->getNodeType() == NT_interface) { + if (idlc()->error()->checkPublished(decl)) { + idlc()->scopes()->top()->addDeclaration(decl); + } + } else { + idlc()->error()->lookupError( + EIDL_INTERFACEMEMBER_LOOKUP, *$2, scopeAsDecl(scope)); + } + delete $2; + } + ; + +service_obsolete_dfn: + '{' + { + idlc()->setParseState( + idlc()->scopes()->top()->getScopeNodeType() == NT_service + ? PS_ServiceSqSeen : PS_SingletonSqSeen); + } + service_exports + { + idlc()->setParseState( + idlc()->scopes()->top()->getScopeNodeType() == NT_service + ? PS_ServiceBodySeen : PS_SingletonBodySeen); + } + '}' + { + idlc()->setParseState( + idlc()->scopes()->top()->getScopeNodeType() == NT_service + ? PS_ServiceQsSeen : PS_SingletonQsSeen); + } + ; + +type_dcl : + IDL_TYPEDEF + { + idlc()->setParseState(PS_TypedefSeen); + } + type_declarator {} + | struct_type {} + | union_type {} + | enum_type {} + ; + +type_declarator : + type_spec + { + idlc()->setParseState(PS_TypeSpecSeen); + if ($1 != 0 && $1->getNodeType() == NT_instantiated_struct) { + idlc()->error()->error0(EIDL_INSTANTIATED_STRUCT_TYPE_TYPEDEF); + } + } + at_least_one_declarator + { + idlc()->setParseState(PS_DeclaratorsSeen); + + AstScope* pScope = idlc()->scopes()->topNonNull(); + AstTypeDef* pTypeDef = NULL; + FeDeclList* pList = $3; + FeDeclarator* pDecl = NULL; + AstType const * pType = NULL; + + /* + * Create nodes representing typedefs and add them to the + * enclosing scope + */ + if ( pScope && $1 && pList ) + { + FeDeclList::iterator iter = pList->begin(); + FeDeclList::iterator end = pList->end(); + + while (iter != end) + { + pDecl = (*iter); + if ( !pDecl ) + { + iter++; + continue; + } + + pType = pDecl->compose($1); + + if ( !pType ) + { + iter++; + continue; + } + + pTypeDef = new AstTypeDef(pType, pDecl->getName(), pScope); + + pScope->addDeclaration(pTypeDef); + iter++; + delete pDecl; + } + delete pList; + } + } + ; + +at_least_one_declarator : + declarator declarators + { + if ( $2 ) + { + $2->push_back($1); + $$ = $2; + } else + { + FeDeclList* pList = new FeDeclList(); + pList->push_back($1); + $$ = pList; + } + } + ; + +declarators : + declarators + ',' + { + idlc()->setParseState(PS_DeclsCommaSeen); + } + declarator + { + idlc()->setParseState(PS_DeclsDeclSeen); + if ( $1 ) + { + $1->push_back($4); + $$ = $1; + } else + { + FeDeclList* pList = new FeDeclList(); + pList->push_back($4); + $$ = pList; + } + } + | /* EMPTY */ + { + $$ = NULL; + } + ; + +declarator : + simple_declarator + | complex_declarator + ; + +simple_declarator : + identifier + { + // For historic reasons, the struct com.sun.star.uno.Uik contains + // members with illegal names (of the form "m_DataN"); avoid useless + // warnings about them: + AstScope * scope = idlc()->scopes()->top(); + if (scope == 0 || scope->getScopeNodeType() != NT_struct + || (scopeAsDecl(scope)->getScopedName() + != "com::sun::star::uno::Uik")) + { + checkIdentifier($1); + } + + $$ = new FeDeclarator(*$1, FeDeclarator::FD_simple, NULL); + delete $1; + } + ; + +complex_declarator : + array_declarator + { + $$ = new FeDeclarator($1->getLocalName(), FeDeclarator::FD_complex, $1); + } + ; + +array_declarator : + identifier + { + idlc()->setParseState(PS_ArrayIDSeen); + checkIdentifier($1); + } + at_least_one_array_dim + { + idlc()->setParseState(PS_ArrayCompleted); + $$ = new AstArray(*$1, NULL, *$3, idlc()->scopes()->bottom()); + delete $1; + } + ; + +at_least_one_array_dim : + array_dim array_dims + { + if( $2 ) + { + $2->push_front($1); + $$ = $2; + } else + { + ExprList* pList = new ExprList(); + pList->push_back($1); + $$ = pList; + } + } + ; + +array_dims : + array_dims array_dim + { + if( $1 ) + { + $1->push_back($2); + $$ = $1; + } else + { + ExprList* pList = new ExprList(); + pList->push_back($2); + $$ = pList; + } + } + | /* EMPTY */ + { + $$ = NULL; + } + ; + +array_dim : + '[' + { + idlc()->setParseState(PS_DimSqSeen); + } + positive_int_expr + { + idlc()->setParseState(PS_DimExprSeen); + } + ']' + { + idlc()->setParseState(PS_DimQsSeen); + /* + * Array dimensions are expressions which must be coerced to + * positive integers + */ + if ( !$3 || !$3->coerce(ET_uhyper) ) + { + idlc()->error()->coercionError($3, ET_uhyper); + $$ = NULL; + } else + $$ = $3; + } + ; + +at_least_one_scoped_name : + scoped_name scoped_names + { + if ($2) + { + $2->push_front(*$1); + $$ = $2; + } else + { + StringList* pNames = new StringList(); + pNames->push_back(*$1); + $$ = pNames; + } + delete($1); + } + ; + +scoped_names : + scoped_names + ',' + { + idlc()->setParseState(PS_SNListCommaSeen); + } + scoped_name + { + idlc()->setParseState(PS_ScopedNameSeen); + if ($1) + { + $1->push_back(*$4); + $$ = $1; + } else + { + StringList* pNames = new StringList(); + pNames->push_back(*$4); + $$ = pNames; + } + delete($4); + } + | /* EMPTY */ + { + $$ = NULL; + } + ; + +scoped_name : + identifier + { + idlc()->setParseState(PS_SN_IDSeen); + checkIdentifier($1); + $$ = $1; + } + | IDL_SCOPESEPARATOR + { + idlc()->setParseState(PS_ScopeDelimSeen); + } + identifier + { + checkIdentifier($3); + OString* pName = new OString("::"); + *pName += *$3; + delete $3; + $$ = pName; + } + | scoped_name + IDL_SCOPESEPARATOR + { + } + identifier + { + checkIdentifier($4); + *$1 += ::rtl::OString("::"); + *$1 += *$4; + delete $4; + $$ = $1; + } + ; + +type_spec : + simple_type_spec + | constructed_type_spec + ; + +simple_type_spec : + fundamental_type + | scoped_name opt_type_args + { + $$ = createNamedType($1, $2); + } + ; + +fundamental_type: + base_type_spec + { + $$ = idlc()->scopes()->bottom()->lookupPrimitiveType($1); + } + | template_type_spec + ; + +opt_type_args: + '<' type_args '>' { $$ = $2; } + | /* empty */ { $$ = 0; } + ; + +type_args: + type_arg + { + $$ = new DeclList; + $$->push_back(const_cast< AstDeclaration * >($1)); //TODO: const_cast + } + | type_args ',' type_arg + { + $1->push_back(const_cast< AstDeclaration * >($3)); //TODO: const_cast + $$ = $1; + } + ; + +type_arg: + simple_type_spec + { + if ($1 != 0 && static_cast< AstType const * >($1)->isUnsigned()) { + idlc()->error()->error0(EIDL_UNSIGNED_TYPE_ARGUMENT); + } + $$ = $1; + } + ; + +base_type_spec : + integer_type + | floating_pt_type + | char_type + | boolean_type + | byte_type + | any_type + | type_type + | string_type + ; + +integer_type : + signed_int + | unsigned_int + ; + +signed_int : + IDL_LONG + { + $$ = ET_long; + } + | IDL_HYPER + { + $$ = ET_hyper; + } + | IDL_SHORT + { + $$ = ET_short; + } + ; + +unsigned_int : + IDL_UNSIGNED IDL_LONG + { + $$ = ET_ulong; + } + | IDL_UNSIGNED IDL_HYPER + { + $$ = ET_uhyper; + } + | IDL_UNSIGNED IDL_SHORT + { + $$ = ET_ushort; + } + ; + +floating_pt_type : + IDL_DOUBLE + { + $$ = ET_double; + } + | IDL_FLOAT + { + $$ = ET_float; + } + ; + +char_type : + IDL_CHAR + { + $$ = ET_char; + } + ; + +byte_type : + IDL_BYTE + { + $$ = ET_byte; + } + ; + +boolean_type : + IDL_BOOLEAN + { + $$ = ET_boolean; + } + ; + +any_type : + IDL_ANY + { + $$ = ET_any; + } + ; + +type_type : + IDL_TYPE + { + $$ = ET_type; + } + ; + +string_type : + IDL_STRING + { + $$ = ET_string; + } + ; + +template_type_spec : + sequence_type_spec + | array_type + ; + +constructed_type_spec : + struct_type + | union_type + | enum_type + ; + +array_type : + simple_type_spec + { + idlc()->setParseState(PS_ArrayTypeSeen); + } + at_least_one_array_dim + { + idlc()->setParseState(PS_ArrayCompleted); + + AstScope* pScope = idlc()->scopes()->bottom(); + AstDeclaration* pDecl = NULL; + AstDeclaration* pArray = NULL; + + if ( $1 ) + { + pArray = new AstArray((AstType*)$1, *$3, idlc()->scopes()->bottom()); + if ( pScope ) + { + pDecl = pScope->addDeclaration(pArray); + if ( pArray != pDecl ) + { + // if array type already defined then use it + delete pArray; + pArray = pDecl; + } + } + } + $$ = pArray; + } + ; + +sequence_type_spec : + IDL_SEQUENCE + { + idlc()->setParseState(PS_SequenceSeen); + /* + * Push a sequence marker on scopes stack + */ + idlc()->scopes()->push(NULL); + } + '<' + { + idlc()->setParseState(PS_SequenceSqSeen); + } + simple_type_spec + { + idlc()->setParseState(PS_SequenceTypeSeen); + } + '>' + { + idlc()->setParseState(PS_SequenceQsSeen); + /* + * Remove sequence marker from scopes stack + */ + if (idlc()->scopes()->top() == NULL) + idlc()->scopes()->pop(); + /* + * Create a node representing a sequence + */ + AstScope* pScope = idlc()->scopes()->bottom(); + AstDeclaration* pDecl = NULL; + AstDeclaration* pSeq = NULL; + + if ( $5 ) + { + AstType *pType = (AstType*)$5; + if ( pType ) + { + pSeq = new AstSequence(pType, pScope); + /* + * Add this AstSequence to the types defined in the global scope + */ + pDecl = pScope->addDeclaration(pSeq); + if ( pSeq != pDecl ) + { + // if sequence type already defined then use it + delete pSeq; + pSeq = pDecl; + } + } + } + $$ = pSeq; + } + | error '>' + { + yyerror("sequence declaration"); + yyerrok; + $$ = 0; + } + ; + +struct_type : + structure_header + { + idlc()->setParseState(PS_StructHeaderSeen); + + AstScope* pScope = idlc()->scopes()->topNonNull(); + AstStruct* pStruct = NULL; + + if ( pScope ) + { + AstStruct* pBase= static_cast< AstStruct* >($1->getInherits()); + pStruct = new AstStruct( + *$1->getName(), $1->getTypeParameters(), pBase, pScope); + pScope->addDeclaration(pStruct); + } + /* + * Push the scope of the struct on the scopes stack + */ + idlc()->scopes()->push(pStruct); + delete $1; + } + '{' + { + idlc()->setParseState(PS_StructSqSeen); + } + at_least_one_member + { + idlc()->setParseState(PS_StructBodySeen); + } + '}' + { + idlc()->setParseState(PS_StructQsSeen); + /* this exception is finished, pop its scope from the stack */ + idlc()->scopes()->pop(); + } + ; + +structure_header : + IDL_STRUCT + { + idlc()->setParseState(PS_StructSeen); + } + identifier + { + idlc()->setParseState(PS_StructIDSeen); + checkIdentifier($3); + } + opt_type_params + inheritance_spec + { + idlc()->setParseState(PS_InheritSpecSeen); + + // Polymorphic struct type templates with base types would cause various + // problems in language bindings, so forbid them here. For example, + // GCC prior to version 3.4 fails with code like + // + // struct Base { ... }; + // template< typename typeparam_T > struct Derived: public Base { + // int member1 CPPU_GCC3_ALIGN(Base); + // ... }; + // + // (Note that plain struct types with instantiated polymorphic struct + // type bases, which might also cause problems in language bindings, are + // already rejected on a syntactic level.) + if ($5 != 0 && $6 != 0) { + idlc()->error()->error0(EIDL_STRUCT_TYPE_TEMPLATE_WITH_BASE); + } + + $$ = new FeInheritanceHeader(NT_struct, $3, $6, $5); + delete $5; + delete $6; + } + ; + +opt_type_params: + '<' type_params '>' { $$ = $2; } + | /* empty */ { $$ = 0; } + ; + +type_params: + identifier + { + $$ = new std::vector< rtl::OString >; + $$->push_back(*$1); + delete $1; + } + | type_params ',' identifier + { + if (std::find($1->begin(), $1->end(), *$3) != $1->end()) { + idlc()->error()->error0(EIDL_IDENTICAL_TYPE_PARAMETERS); + } + $1->push_back(*$3); + delete $3; + $$ = $1; + } + ; + +at_least_one_member : member members ; + +members : + members member + | /* EMPTY */ + ; + +member : + type_or_parameter + { + idlc()->setParseState(PS_MemberTypeSeen); + } + at_least_one_declarator + { + idlc()->setParseState(PS_MemberDeclsSeen); + } + ';' + { + idlc()->setParseState(PS_MemberDeclsCompleted); + + AstScope* pScope = idlc()->scopes()->topNonNull(); + AstMember* pMember = NULL; + FeDeclList* pList = $3; + FeDeclarator* pDecl = NULL; + AstType const * pType = NULL; + + // !!! check recursive type + + if ( pScope && pList && $1 ) + { + FeDeclList::iterator iter = pList->begin(); + FeDeclList::iterator end = pList->end(); + while (iter != end) + { + pDecl = (*iter); + if ( !pDecl ) + { + iter++; + continue; + } + + pType = pDecl->compose($1); + + if ( !pType ) + { + iter++; + continue; + } + + pMember = new AstMember(pType, pDecl->getName(), pScope); + + if ( !pDecl->checkType($1) ) + { + // WARNING + } + + pScope->addDeclaration(pMember); + iter++; + delete pDecl; + } + delete pList; + } + } + | error ';' + { + yyerror("member definition"); + yyerrok; + } + ; + +type_or_parameter: + fundamental_type + | scoped_name opt_type_args + { + AstDeclaration const * decl = 0; + AstStruct * scope = static_cast< AstStruct * >(idlc()->scopes()->top()); + if (scope != 0 && $2 == 0) { + decl = scope->findTypeParameter(*$1); + } + if (decl != 0) { + delete $1; + delete $2; + } else { + decl = createNamedType($1, $2); + if (scope != 0 && includes(decl, scopeAsDecl(scope))) { + idlc()->error()->error1( + EIDL_RECURSIVE_TYPE, scopeAsDecl(scope)); + decl = 0; + } + } + $$ = decl; + } + ; + +enum_type : + IDL_ENUM + { + idlc()->setParseState(PS_EnumSeen); + } + identifier + { + idlc()->setParseState(PS_EnumIDSeen); + checkIdentifier($3); + + AstScope* pScope = idlc()->scopes()->topNonNull(); + AstEnum* pEnum = NULL; + + /* + * Create a node representing an enum and add it to its + * enclosing scope + */ + if (pScope != NULL) + { + pEnum = new AstEnum(*$3, pScope); + /* + * Add it to its defining scope + */ + pScope->addDeclaration(pEnum); + } + delete $3; + /* + * Push the enum scope on the scopes stack + */ + idlc()->scopes()->push(pEnum); + + } + '{' + { + idlc()->setParseState(PS_EnumSqSeen); + } + at_least_one_enumerator + { + idlc()->setParseState(PS_EnumBodySeen); + } + '}' + { + idlc()->setParseState(PS_EnumQsSeen); + /* + * Done with this enum. Pop its scope from the scopes stack + */ + if (idlc()->scopes()->top() == NULL) + $$ = NULL; + else + { + $$ = (AstEnum*)idlc()->scopes()->topNonNull(); + idlc()->scopes()->pop(); + } + } + ; + +at_least_one_enumerator : enumerator enumerators ; + +enumerators : + enumerators + ',' + { + idlc()->setParseState(PS_EnumCommaSeen); + } + enumerator + | /* EMPTY */ + | error ',' + { + yyerror("enumerator definition"); + yyerrok; + } + ; + +enumerator : + identifier + { + checkIdentifier($1); + + AstScope* pScope = idlc()->scopes()->topNonNull(); + AstEnum* pEnum = NULL; + AstConstant* pEnumVal = NULL; + + if ( pScope && pScope->getScopeNodeType() == NT_enum) + { + pEnum = (AstEnum*)pScope; + if (pEnum && $1) + { + AstExpression* pExpr = new AstExpression(pEnum->getEnumValueCount()); + pEnumVal = new AstConstant(ET_long , NT_enum_val, + pExpr, *$1, pScope); + } + if ( pEnum->checkValue(pEnumVal->getConstValue()) ) + idlc()->error()->error1(EIDL_EVAL_ERROR, pEnum); + + pScope->addDeclaration(pEnumVal); + } + delete $1; + } + | identifier + '=' + const_expr + { + checkIdentifier($1); + + AstScope* pScope = idlc()->scopes()->topNonNull(); + AstEnum* pEnum = NULL; + AstConstant* pEnumVal = NULL; + + if ( $3 && pScope && pScope->getScopeNodeType() == NT_enum) + { + $3->evaluate(EK_const); + if ( $3->coerce(ET_long) ) + { + pEnum = (AstEnum*)pScope; + if (pEnum) + { + pEnumVal = new AstConstant(ET_long , NT_enum_val, + $3, *$1, pScope); + } + if ( pEnum->checkValue(pEnumVal->getConstValue()) ) + idlc()->error()->error1(EIDL_EVAL_ERROR, pEnum); + + pScope->addDeclaration(pEnumVal); + } else + { + idlc()->error()->coercionError($3, ET_long); + delete $3; + } + } + delete $1; + } + ; + +union_type : + IDL_UNION + { + idlc()->setParseState(PS_UnionSeen); + } + identifier + { + idlc()->setParseState(PS_UnionIDSeen); + checkIdentifier($3); + } + IDL_SWITCH + { + idlc()->setParseState(PS_SwitchSeen); + } + '(' + { + idlc()->setParseState(PS_SwitchOpenParSeen); + } + switch_type_spec + { + idlc()->setParseState(PS_SwitchTypeSeen); + } + ')' + { + idlc()->setParseState(PS_SwitchCloseParSeen); + + AstScope* pScope = idlc()->scopes()->topNonNull(); + AstUnion* pUnion = NULL; + + /* + * Create a node representing a union. Add it to its enclosing + * scope + */ + if ( $9 && pScope ) + { + AstType* pType = (AstType*)$9; + if ( !pType) + { + idlc()->error()->noTypeError($9); + } else + { + pUnion = new AstUnion(*$3, pType, pScope); + pScope->addDeclaration(pUnion); + } + } + delete $3; + /* + * Push the scope of the union on the scopes stack + */ + idlc()->scopes()->push(pUnion); + } + '{' + { + idlc()->setParseState(PS_UnionSqSeen); + } + at_least_one_case_branch + { + idlc()->setParseState(PS_UnionBodySeen); + } + '}' + { + idlc()->setParseState(PS_UnionQsSeen); + /* this union is finished, pop its scope from the stack */ + idlc()->scopes()->pop(); + } + ; + +switch_type_spec : + integer_type + { + $$ = idlc()->scopes()->bottom()->lookupPrimitiveType($1); + } + | char_type + { + $$ = idlc()->scopes()->bottom()->lookupPrimitiveType($1); + } + | boolean_type + { + $$ = idlc()->scopes()->bottom()->lookupPrimitiveType($1); + } + | enum_type + | scoped_name + { + AstScope* pScope = idlc()->scopes()->topNonNull(); + AstBaseType* pBaseType = NULL; + AstDeclaration const * pDecl = NULL; + AstTypeDef* pTypeDef = NULL; + sal_Bool bFound = sal_False; + /* + * If the constant's type is a scoped name, it must resolve + * to a scalar constant type + */ + if ( pScope && (pDecl = pScope->lookupByName(*$1)) ) + { + /* + * Look through typedefs + */ + while ( !bFound ) + { + switch (pDecl->getNodeType()) + { + case NT_enum: + $$ = pDecl; + bFound = sal_True; + break; + case NT_predefined: + pBaseType = (AstBaseType*)pDecl; + if ( pBaseType ) + { + switch (pBaseType->getExprType()) + { + case ET_short: + case ET_ushort: + case ET_long: + case ET_ulong: + case ET_hyper: + case ET_uhyper: + case ET_char: + case ET_byte: + case ET_boolean: + $$ = pBaseType; + bFound = sal_True; + break; + default: + $$ = NULL; + bFound = sal_True; + break; + } + } + break; + case NT_typedef: + pTypeDef = (AstTypeDef*)pDecl; + if ( pTypeDef ) + pDecl = pTypeDef->getBaseType(); + break; + default: + $$ = NULL; + bFound = sal_True; + break; + } + } + } else + $$ = NULL; + + if ($$ == NULL) + idlc()->error()->lookupError(*$1); + } + ; + +at_least_one_case_branch : case_branch case_branches ; + +case_branches : + case_branches case_branch + | /* EMPTY */ + ; + +case_branch : + at_least_one_case_label + { + idlc()->setParseState(PS_UnionLabelSeen); + } + element_spec + { + idlc()->setParseState(PS_UnionElemSeen); + + AstScope* pScope = idlc()->scopes()->topNonNull(); + AstUnionLabel* pLabel = NULL; + AstUnionBranch* pBranch = NULL; + AstMember* pMember = $3; + + /* + * Create several nodes representing branches of a union. + * Add them to the enclosing scope (the union scope) + */ + if ( pScope && $1 && $3 ) + { + LabelList::iterator iter = $1->begin(); + LabelList::iterator end = $1->end(); + for (;iter != end; iter++) + { + pLabel = *iter; + if ( !pLabel ) + { + iter++; + continue; + } + pBranch = new AstUnionBranch(pLabel, pMember->getType(), + pMember->getLocalName(), pScope); + pScope->addDeclaration(pBranch); + } + } + if ( $1 ) delete($1); + } + ; + +at_least_one_case_label : + case_label case_labels + { + if ( $2 ) + { + $2->push_front($1); + $$ = $2; + } else + { + LabelList* pLabels = new LabelList(); + pLabels->push_back($1); + $$ = pLabels; + } + } + ; + +case_labels : + case_labels case_label + { + if ( $1 ) + { + $1->push_back($2); + $$ = $1; + } else + { + LabelList* pLabels = new LabelList(); + pLabels->push_back($2); + $$ = pLabels; + } + } + | /* EMPTY */ + { + $$ = NULL; + } + ; + +case_label : + IDL_DEFAULT + { + idlc()->setParseState(PS_DefaultSeen); + } + ':' + { + idlc()->setParseState(PS_LabelColonSeen); + $$ = new AstUnionLabel(UL_default, NULL); + } + | IDL_CASE + { + idlc()->setParseState(PS_CaseSeen); + } + const_expr + { + idlc()->setParseState(PS_LabelExprSeen); + } + ':' + { + idlc()->setParseState(PS_LabelColonSeen); + $$ = new AstUnionLabel(UL_label, $3); + } + ; + +element_spec : + type_spec + { + idlc()->setParseState(PS_UnionElemTypeSeen); + } + declarator + { + idlc()->setParseState(PS_UnionElemDeclSeen); + } + ';' + { + idlc()->setParseState(PS_UnionElemCompleted); + + AstScope* pScope = idlc()->scopes()->topNonNull(); + /* + * Check for illegal recursive use of type + */ +// if ( $1 && AST_illegal_recursive_type($1)) +// idlc()->error()->error1(EIDL_RECURSIVE_TYPE, $1); + /* + * Create a field in a union branch + */ + if ( $1 && $3 ) + { + AstType const * pType = $3->compose($1); + if ( !pType ) + $$ = NULL; + else + $$ = new AstMember(pType, $3->getName(), pScope); + } else + $$ = NULL; + + if ( $3 ) delete $3; + } + | error + ';' + { + $$ = NULL; + } + ; + +identifier: + IDL_IDENTIFIER + | IDL_GET { $$ = new OString("get"); } + | IDL_SET { $$ = new OString("set"); } + | IDL_PUBLISHED { $$ = new OString("published"); } + ; + +%% + +/* + * Report an error situation discovered in a production + */ +void yyerror(char const *errmsg) +{ + idlc()->error()->syntaxError(idlc()->getParseState(), idlc()->getLineNumber(), errmsg); + idlc()->setParseState(PS_NoState); +} diff --git a/idlc/source/preproc/cpp.c b/idlc/source/preproc/cpp.c new file mode 100644 index 000000000000..59e0b615cae9 --- /dev/null +++ b/idlc/source/preproc/cpp.c @@ -0,0 +1,498 @@ +/************************************************************************* + * + * 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 <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <stdarg.h> +#include "cpp.h" + +#define OUTS 16384 +char outbuf[OUTS]; +char *outptr = outbuf; +Source *cursource; +int nerrs; +struct token nltoken = {NL, 0, 0, 1, (uchar *) "\n"}; +char *curtime; +int incdepth; +int ifdepth; +int ifsatisfied[NIF]; +int skipping; + +char rcsid[] = "$Version 1.2 $ $Revision: 1.10 $ $Date: 2008-07-11 14:50:24 $"; + +int realargc; +char* realargv[512]; + +void checkCommandFile(char* cmdfile) +{ + FILE *commandfile; + char option[256]; + + commandfile = fopen(cmdfile+1, "r"); + if( commandfile == NULL ) + { + error(FATAL, "Can't open command file %s", cmdfile); + } else + { + int i=0; + int found = 0; + char c; + while ( fscanf(commandfile, "%c", &c) != EOF ) + { + if (c=='\"') { + if (found) { + found=0; + } else { + found=1; + continue; + } + } else { + if (c!=13 && c!=10) { + if (found || c!=' ') { + option[i++]=c; + continue; + } + } + if (i==0) + continue; + } + option[i]='\0'; + found=0; + i=0; + if (option[0]== '@' || option[1]== '@') + { + checkCommandFile(option); + } else + { + realargv[realargc]= strdup(option); + realargc++; + option[0]='\0'; + } + } + if (option[0] != '\0') { + option[i]='\0'; + realargv[realargc]= strdup(option); + realargc++; + } + fclose(commandfile); + } +} + +void checkCommandArgs(int argc, char **argv) +{ + int i; + + for (i=0; i<argc; i++) + { + if (argv[i][0]== '@') + { + checkCommandFile(argv[i]); + } else + { + realargv[i]= strdup(argv[i]); + realargc++; + } + } +} + +void cleanCommandArgs() +{ + int i; + + for (i=0; i<realargc; i++) + { + free(realargv[i]); + } +} + +#ifdef WNT +int __cdecl main(int argc, char **argv) +#else +int main(int argc, char **argv) +#endif +{ + Tokenrow tr; + time_t t; + char ebuf[BUFSIZ]; + + checkCommandArgs(argc, argv); + + setbuf(stderr, ebuf); + t = time(NULL); + curtime = ctime(&t); + maketokenrow(3, &tr); + expandlex(); + setup(realargc, realargv); + if (!Pflag) + genline(); + process(&tr); + flushout(); + fflush(stderr); + cleanCommandArgs(); + exit(nerrs); + //return nerrs; +} + +void + process(Tokenrow * trp) +{ + int anymacros = 0; + + for (;;) + { + if (trp->tp >= trp->lp) + { + trp->tp = trp->lp = trp->bp; + outptr = outbuf; + anymacros |= gettokens(trp, 1); + trp->tp = trp->bp; + } + if (trp->tp->type == END) + { + if (--incdepth >= 0) + { + if (cursource->ifdepth) + error(ERROR, + "Unterminated conditional in #include"); + unsetsource(); + cursource->line += cursource->lineinc; + trp->tp = trp->lp; + if (!Pflag) + genline(); + continue; + } + if (ifdepth) + error(ERROR, "Unterminated #if/#ifdef/#ifndef"); + break; + } + if (trp->tp->type == SHARP) + { + trp->tp += 1; + control(trp); + } + else + if (!skipping && anymacros) + expandrow(trp, NULL); + if (skipping) + setempty(trp); + puttokens(trp); + anymacros = 0; + cursource->line += cursource->lineinc; + if (cursource->lineinc > 1) + { + if (!Pflag) + genline(); + } + } +} + +void + control(Tokenrow * trp) +{ + Nlist *np; + Token *tp; + + tp = trp->tp; + if (tp->type != NAME) + { + if (tp->type == NUMBER) + goto kline; + if (tp->type != NL) + error(ERROR, "Unidentifiable control line"); + return; /* else empty line */ + } + if ((np = lookup(tp, 0)) == NULL || ((np->flag & ISKW) == 0 && !skipping)) + { + error(WARNING, "Unknown preprocessor control %t", tp); + return; + } + if (skipping) + { + switch (np->val) + { + case KENDIF: + if (--ifdepth < skipping) + skipping = 0; + --cursource->ifdepth; + setempty(trp); + return; + + case KIFDEF: + case KIFNDEF: + case KIF: + if (++ifdepth >= NIF) + error(FATAL, "#if too deeply nested"); + ++cursource->ifdepth; + return; + + case KELIF: + case KELSE: + if (ifdepth <= skipping) + break; + return; + + default: + return; + } + } + switch (np->val) + { + case KDEFINE: + dodefine(trp); + break; + + case KUNDEF: + tp += 1; + if (tp->type != NAME || trp->lp - trp->bp != 4) + { + error(ERROR, "Syntax error in #undef"); + break; + } + if ((np = lookup(tp, 0)) != NULL) + { + np->flag &= ~ISDEFINED; + + if (Mflag) + { + if (np->ap) + error(INFO, "Macro deletion of %s(%r)", np->name, np->ap); + else + error(INFO, "Macro deletion of %s", np->name); + } + } + break; + + case KPRAGMA: + case KIDENT: + for (tp = trp->tp - 1; ((tp->type != NL) && (tp < trp->lp)); tp++) + tp->type = UNCLASS; + return; + + case KIFDEF: + case KIFNDEF: + case KIF: + if (++ifdepth >= NIF) + error(FATAL, "#if too deeply nested"); + ++cursource->ifdepth; + ifsatisfied[ifdepth] = 0; + if (eval(trp, np->val)) + ifsatisfied[ifdepth] = 1; + else + skipping = ifdepth; + break; + + case KELIF: + if (ifdepth == 0) + { + error(ERROR, "#elif with no #if"); + return; + } + if (ifsatisfied[ifdepth] == 2) + error(ERROR, "#elif after #else"); + if (eval(trp, np->val)) + { + if (ifsatisfied[ifdepth]) + skipping = ifdepth; + else + { + skipping = 0; + ifsatisfied[ifdepth] = 1; + } + } + else + skipping = ifdepth; + break; + + case KELSE: + if (ifdepth == 0 || cursource->ifdepth == 0) + { + error(ERROR, "#else with no #if"); + return; + } + if (ifsatisfied[ifdepth] == 2) + error(ERROR, "#else after #else"); + if (trp->lp - trp->bp != 3) + error(ERROR, "Syntax error in #else"); + skipping = ifsatisfied[ifdepth] ? ifdepth : 0; + ifsatisfied[ifdepth] = 2; + break; + + case KENDIF: + if (ifdepth == 0 || cursource->ifdepth == 0) + { + error(ERROR, "#endif with no #if"); + return; + } + --ifdepth; + --cursource->ifdepth; + if (trp->lp - trp->bp != 3) + error(WARNING, "Syntax error in #endif"); + break; + + case KERROR: + trp->tp = tp + 1; + error(WARNING, "#error directive: %r", trp); + break; + + case KLINE: + trp->tp = tp + 1; + expandrow(trp, "<line>"); + tp = trp->bp + 2; + kline: + if (tp + 1 >= trp->lp || tp->type != NUMBER || tp + 3 < trp->lp + || (tp + 3 == trp->lp + && ((tp + 1)->type != STRING || *(tp + 1)->t == 'L'))) + { + error(ERROR, "Syntax error in #line"); + return; + } + cursource->line = atol((char *) tp->t) - 1; + if (cursource->line < 0 || cursource->line >= 32768) + error(WARNING, "#line specifies number out of range"); + tp = tp + 1; + if (tp + 1 < trp->lp) + cursource->filename = (char *) newstring(tp->t + 1, tp->len - 2, 0); + return; + + case KDEFINED: + error(ERROR, "Bad syntax for control line"); + break; + + case KIMPORT: + doinclude(trp, -1, 1); + trp->lp = trp->bp; + return; + + case KINCLUDE: + doinclude(trp, -1, 0); + trp->lp = trp->bp; + return; + + case KINCLUDENEXT: + doinclude(trp, cursource->pathdepth, 0); + trp->lp = trp->bp; + return; + + case KEVAL: + eval(trp, np->val); + break; + + default: + error(ERROR, "Preprocessor control `%t' not yet implemented", tp); + break; + } + setempty(trp); + return; +} + +void * + domalloc(int size) +{ + void *p = malloc(size); + + if (p == NULL) + error(FATAL, "Out of memory from malloc"); + return p; +} + +void + dofree(void *p) +{ + free(p); +} + +void + error(enum errtype type, char *string,...) +{ + va_list ap; + char c, *cp, *ep; + Token *tp; + Tokenrow *trp; + Source *s; + int i; + + fprintf(stderr, "cpp: "); + for (s = cursource; s; s = s->next) + if (*s->filename) + fprintf(stderr, "%s:%d ", s->filename, s->line); + va_start(ap, string); + for (ep = string; *ep; ep++) + { + if (*ep == '%') + { + switch (*++ep) + { + + case 'c': + /* need a cast here since va_arg only + takes fully promoted types */ + c = (char) va_arg(ap, int); + fprintf(stderr, "%c", c); + break; + + case 's': + cp = va_arg(ap, char *); + fprintf(stderr, "%s", cp); + break; + + case 'd': + i = va_arg(ap, int); + fprintf(stderr, "%d", i); + break; + + case 't': + tp = va_arg(ap, Token *); + fprintf(stderr, "%.*s", tp->len, tp->t); + break; + + case 'r': + trp = va_arg(ap, Tokenrow *); + for (tp = trp->tp; tp < trp->lp && tp->type != NL; tp++) + { + if (tp > trp->tp && tp->wslen) + fputc(' ', stderr); + fprintf(stderr, "%.*s", tp->len, tp->t); + } + break; + + default: + fputc(*ep, stderr); + break; + } + } + else + fputc(*ep, stderr); + } + va_end(ap); + fputc('\n', stderr); + if (type == FATAL) + exit(-1); + if (type != WARNING) + nerrs += 1; + fflush(stderr); +} diff --git a/idlc/source/preproc/cpp.h b/idlc/source/preproc/cpp.h new file mode 100644 index 000000000000..4b8645b2d34e --- /dev/null +++ b/idlc/source/preproc/cpp.h @@ -0,0 +1,213 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#define INS 32768 /* input buffer */ +#define OBS 8092 /* outbut buffer */ +#define NARG 32 /* Max number arguments to a macro */ +#define NINCLUDE 32 /* Max number of include directories (-I) */ +#define NIF 64 /* depth of nesting of #if */ +#define NINC 32 /* depth of nesting of #include */ + +#ifndef EOF +#define EOF (-1) +#endif + +#ifndef NULL +#define NULL 0 +#endif + +typedef unsigned char uchar; + +enum toktype +{ + END, UNCLASS, NAME, NUMBER, STRING, CCON, NL, WS, DSHARP, + EQ, NEQ, LEQ, GEQ, LSH, RSH, LAND, LOR, PPLUS, MMINUS, + ARROW, SBRA, SKET, LP, RP, DOT, AND, STAR, PLUS, MINUS, + TILDE, NOT, SLASH, PCT, LT, GT, CIRC, OR, QUEST, + COLON, ASGN, COMMA, SHARP, SEMIC, CBRA, CKET, + ASPLUS, ASMINUS, ASSTAR, ASSLASH, ASPCT, ASCIRC, ASLSH, + ASRSH, ASOR, ASAND, ELLIPS, + DSHARP1, NAME1, NAME2, DEFINED, UMINUS, ARCHITECTURE, IDENT, + COMMENT +}; + +enum kwtype +{ + KIF, KIFDEF, KIFNDEF, KELIF, KELSE, KENDIF, KINCLUDE, KINCLUDENEXT, + KIMPORT, KDEFINE, KUNDEF, KLINE, KERROR, KPRAGMA, KIDENT, KDEFINED, + KMACHINE, KLINENO, KFILE, KDATE, KTIME, KSTDC, KEVAL +}; + +#define ISDEFINED 0x01 /* has #defined value */ +#define ISKW 0x02 /* is PP keyword */ +#define ISUNCHANGE 0x04 /* can't be #defined in PP */ +#define ISMAC 0x08 /* builtin macro, e.g. __LINE__ */ +#define ISARCHITECTURE 0x10 /* architecture */ +#define ISACTIVE 0x80 /* is macro currently expanded */ + +#define EOB 0xFE /* sentinel for end of input buffer */ +#define EOFC 0xFD /* sentinel for end of input file */ +#define XPWS 1 /* token flag: white space to assure token sep. */ +#define XTWS 2 + +typedef struct token +{ + unsigned char type; + unsigned char flag; + unsigned int wslen; + unsigned int len; + uchar *t; +} Token; + +typedef struct tokenrow +{ + Token *tp; /* current one to scan */ + Token *bp; /* base (allocated value) */ + Token *lp; /* last+1 token used */ + int max; /* number allocated */ +} Tokenrow; + +typedef struct source +{ + char *filename; /* name of file of the source */ + int line; /* current line number */ + int lineinc; /* adjustment for \\n lines */ + uchar *inb; /* input buffer */ + uchar *inp; /* input pointer */ + uchar *inl; /* end of input */ + int fd; /* input source */ + int ifdepth; /* conditional nesting in include */ + int pathdepth; + int wrap; + struct source *next; /* stack for #include */ +} Source; + +typedef struct nlist +{ + struct nlist *next; + uchar *name; + int len; + Tokenrow *vp; /* value as macro */ + Tokenrow *ap; /* list of argument names, if any */ + char val; /* value as preprocessor name */ + char flag; /* is defined, is pp name */ + uchar *loc; /* location of definition */ +} Nlist; + +typedef struct includelist +{ + char deleted; + char always; + char *file; +} Includelist; + +typedef struct wraplist +{ + char *file; +} Wraplist; + +#define new(t) (t *)domalloc(sizeof(t)) +#define quicklook(a,b) (namebit[(a)&077] & (1<<((b)&037))) +#define quickset(a,b) namebit[(a)&077] |= (1<<((b)&037)) +extern unsigned long namebit[077 + 1]; + +enum errtype +{ + INFO, WARNING, ERROR, FATAL +}; + +void expandlex(void); +void setup(int, char **); +int gettokens(Tokenrow *, int); +int comparetokens(Tokenrow *, Tokenrow *); +Source *setsource(char *, int, int, char *, int); +void unsetsource(void); +void puttokens(Tokenrow *); +void process(Tokenrow *); +void *domalloc(int); +void dofree(void *); +void error(enum errtype, char *,...); +void flushout(void); +int fillbuf(Source *); +int trigraph(Source *); +int foldline(Source *); +Nlist *lookup(Token *, int); +void control(Tokenrow *); +void dodefine(Tokenrow *); +void doadefine(Tokenrow *, int); +void doinclude(Tokenrow *, int, int); +void doif(Tokenrow *, enum kwtype); +void expand(Tokenrow *, Nlist *); +void builtin(Tokenrow *, int); +int gatherargs(Tokenrow *, Tokenrow **, int *); +void substargs(Nlist *, Tokenrow *, Tokenrow **); +void expandrow(Tokenrow *, char *); +void maketokenrow(int, Tokenrow *); +Tokenrow *copytokenrow(Tokenrow *, Tokenrow *); +Token *growtokenrow(Tokenrow *); +Tokenrow *normtokenrow(Tokenrow *); +void adjustrow(Tokenrow *, int); +void movetokenrow(Tokenrow *, Tokenrow *); +void insertrow(Tokenrow *, int, Tokenrow *); +void peektokens(Tokenrow *, char *); +void doconcat(Tokenrow *); +Tokenrow *stringify(Tokenrow *); +int lookuparg(Nlist *, Token *); +long eval(Tokenrow *, int); +void genline(void); +void genimport(char *, int, char *, int); +void genwrap(int); +void setempty(Tokenrow *); +void makespace(Tokenrow *, Token *); +char *outnum(char *, int); +int digit(int); +uchar *newstring(uchar *, int, int); + +#define rowlen(tokrow) ((tokrow)->lp - (tokrow)->bp) + +extern char *outptr; +extern Token nltoken; +extern Source *cursource; +extern char *curtime; +extern int incdepth; +extern int ifdepth; +extern int ifsatisfied[NIF]; +extern int Mflag; +extern int Iflag; +extern int Pflag; +extern int Aflag; +extern int Lflag; +extern int Xflag; +extern int Vflag; +extern int Cflag; +extern int Cplusplus; +extern int skipping; +extern Nlist *kwdefined; +extern Includelist includelist[NINCLUDE]; +extern Wraplist wraplist[NINCLUDE]; +extern char wd[]; + diff --git a/idlc/source/preproc/eval.c b/idlc/source/preproc/eval.c new file mode 100644 index 000000000000..cd3adc2204c7 --- /dev/null +++ b/idlc/source/preproc/eval.c @@ -0,0 +1,790 @@ +/************************************************************************* + * + * 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 <stdlib.h> +#include <string.h> +#include "cpp.h" + +#define NSTAK 32 +#define SGN 0 +#define UNS 1 +#define UND 2 + +#define UNSMARK 0x1000 + +struct value +{ + long val; + int type; +}; + +/* conversion types */ +#define RELAT 1 +#define ARITH 2 +#define LOGIC 3 +#define SPCL 4 +#define SHIFT 5 +#define UNARY 6 + +/* operator priority, arity, and conversion type, indexed by tokentype */ +struct pri +{ + char pri; + char arity; + char ctype; +} priority[] = + +{ + { + 0, 0, 0 + }, /* END */ + { + 0, 0, 0 + }, /* UNCLASS */ + { + 0, 0, 0 + }, /* NAME */ + { + 0, 0, 0 + }, /* NUMBER */ + { + 0, 0, 0 + }, /* STRING */ + { + 0, 0, 0 + }, /* CCON */ + { + 0, 0, 0 + }, /* NL */ + { + 0, 0, 0 + }, /* WS */ + { + 0, 0, 0 + }, /* DSHARP */ + { + 11, 2, RELAT + }, /* EQ */ + { + 11, 2, RELAT + }, /* NEQ */ + { + 12, 2, RELAT + }, /* LEQ */ + { + 12, 2, RELAT + }, /* GEQ */ + { + 13, 2, SHIFT + }, /* LSH */ + { + 13, 2, SHIFT + }, /* RSH */ + { + 7, 2, LOGIC + }, /* LAND */ + { + 6, 2, LOGIC + }, /* LOR */ + { + 0, 0, 0 + }, /* PPLUS */ + { + 0, 0, 0 + }, /* MMINUS */ + { + 0, 0, 0 + }, /* ARROW */ + { + 0, 0, 0 + }, /* SBRA */ + { + 0, 0, 0 + }, /* SKET */ + { + 3, 0, 0 + }, /* LP */ + { + 3, 0, 0 + }, /* RP */ + { + 0, 0, 0 + }, /* DOT */ + { + 10, 2, ARITH + }, /* AND */ + { + 15, 2, ARITH + }, /* STAR */ + { + 14, 2, ARITH + }, /* PLUS */ + { + 14, 2, ARITH + }, /* MINUS */ + { + 16, 1, UNARY + }, /* TILDE */ + { + 16, 1, UNARY + }, /* NOT */ + { + 15, 2, ARITH + }, /* SLASH */ + { + 15, 2, ARITH + }, /* PCT */ + { + 12, 2, RELAT + }, /* LT */ + { + 12, 2, RELAT + }, /* GT */ + { + 9, 2, ARITH + }, /* CIRC */ + { + 8, 2, ARITH + }, /* OR */ + { + 5, 2, SPCL + }, /* QUEST */ + { + 5, 2, SPCL + }, /* COLON */ + { + 0, 0, 0 + }, /* ASGN */ + { + 4, 2, 0 + }, /* COMMA */ + { + 0, 0, 0 + }, /* SHARP */ + { + 0, 0, 0 + }, /* SEMIC */ + { + 0, 0, 0 + }, /* CBRA */ + { + 0, 0, 0 + }, /* CKET */ + { + 0, 0, 0 + }, /* ASPLUS */ + { + 0, 0, 0 + }, /* ASMINUS */ + { + 0, 0, 0 + }, /* ASSTAR */ + { + 0, 0, 0 + }, /* ASSLASH */ + { + 0, 0, 0 + }, /* ASPCT */ + { + 0, 0, 0 + }, /* ASCIRC */ + { + 0, 0, 0 + }, /* ASLSH */ + { + 0, 0, 0 + }, /* ASRSH */ + { + 0, 0, 0 + }, /* ASOR */ + { + 0, 0, 0 + }, /* ASAND */ + { + 0, 0, 0 + }, /* ELLIPS */ + { + 0, 0, 0 + }, /* DSHARP1 */ + { + 0, 0, 0 + }, /* NAME1 */ + { + 0, 0, 0 + }, /* NAME2 */ + { + 16, 1, UNARY + }, /* DEFINED */ + { + 16, 0, UNARY + }, /* UMINUS */ + { + 16, 1, UNARY + }, /* ARCHITECTURE */ +}; + +int evalop(struct pri); +struct value tokval(Token *); +struct value vals[NSTAK], *vp; +enum toktype ops[NSTAK], *op; + +/* + * Evaluate an #if #elif #ifdef #ifndef line. trp->tp points to the keyword. + */ +long + eval(Tokenrow * trp, int kw) +{ + Token *tp; + Nlist *np; + int ntok, rand; + + trp->tp++; + if (kw == KIFDEF || kw == KIFNDEF) + { + if (trp->lp - trp->bp != 4 || trp->tp->type != NAME) + { + error(ERROR, "Syntax error in #ifdef/#ifndef"); + return 0; + } + np = lookup(trp->tp, 0); + return (kw == KIFDEF) == (np && np->flag & (ISDEFINED | ISMAC)); + } + ntok = trp->tp - trp->bp; + kwdefined->val = KDEFINED; /* activate special meaning of + * defined */ + expandrow(trp, "<if>"); + kwdefined->val = NAME; + vp = vals; + op = ops; + *op++ = END; + for (rand = 0, tp = trp->bp + ntok; tp < trp->lp; tp++) + { + switch (tp->type) + { + case WS: + case NL: + continue; + + /* nilary */ + case NAME: + case NAME1: + case NAME2: + case NUMBER: + case CCON: + case STRING: + if (rand) + goto syntax; + *vp++ = tokval(tp); + rand = 1; + continue; + + /* unary */ + case DEFINED: + case TILDE: + case NOT: + if (rand) + goto syntax; + *op++ = tp->type; + continue; + + /* unary-binary */ + case PLUS: + case MINUS: + case STAR: + case AND: + if (rand == 0) + { + if (tp->type == MINUS) + *op++ = UMINUS; + if (tp->type == STAR || tp->type == AND) + { + error(ERROR, "Illegal operator * or & in #if/#elsif"); + return 0; + } + continue; + } + /* flow through */ + + /* plain binary */ + case EQ: + case NEQ: + case LEQ: + case GEQ: + case LSH: + case RSH: + case LAND: + case LOR: + case SLASH: + case PCT: + case LT: + case GT: + case CIRC: + case OR: + case QUEST: + case COLON: + case COMMA: + if (rand == 0) + goto syntax; + if (evalop(priority[tp->type]) != 0) + return 0; + *op++ = tp->type; + rand = 0; + continue; + + case LP: + if (rand) + goto syntax; + *op++ = LP; + continue; + + case RP: + if (!rand) + goto syntax; + if (evalop(priority[RP]) != 0) + return 0; + if (op <= ops || op[-1] != LP) + { + goto syntax; + } + op--; + continue; + + case SHARP: + if ((tp + 1) < trp->lp) + { + np = lookup(tp + 1, 0); + if (np && (np->val == KMACHINE)) + { + tp++; + if (rand) + goto syntax; + *op++ = ARCHITECTURE; + continue; + } + } + /* fall through */ + + default: + error(ERROR, "Bad operator (%t) in #if/#elsif", tp); + return 0; + } + } + if (rand == 0) + goto syntax; + if (evalop(priority[END]) != 0) + return 0; + if (op != &ops[1] || vp != &vals[1]) + { + error(ERROR, "Botch in #if/#elsif"); + return 0; + } + if (vals[0].type == UND) + error(ERROR, "Undefined expression value"); + return vals[0].val; +syntax: + error(ERROR, "Syntax error in #if/#elsif"); + return 0; +} + +int + evalop(struct pri pri) +{ + struct value v1, v2 = { 0, 0 }; + long rv1, rv2; + int rtype, oper; + + rv2 = 0; + rtype = 0; + while (pri.pri < priority[op[-1]].pri) + { + oper = *--op; + if (priority[oper].arity == 2) + { + v2 = *--vp; + rv2 = v2.val; + } + v1 = *--vp; + rv1 = v1.val; +/*lint -e574 -e644 */ + switch (priority[oper].ctype) + { + case 0: + default: + error(WARNING, "Syntax error in #if/#endif"); + return 1; + case ARITH: + case RELAT: + if (v1.type == UNS || v2.type == UNS) + rtype = UNS; + else + rtype = SGN; + if (v1.type == UND || v2.type == UND) + rtype = UND; + if (priority[oper].ctype == RELAT && rtype == UNS) + { + oper |= UNSMARK; + rtype = SGN; + } + break; + case SHIFT: + if (v1.type == UND || v2.type == UND) + rtype = UND; + else + rtype = v1.type; + if (rtype == UNS) + oper |= UNSMARK; + break; + case UNARY: + rtype = v1.type; + break; + case LOGIC: + case SPCL: + break; + } + switch (oper) + { + case EQ: + case EQ | UNSMARK: + rv1 = rv1 == rv2; + break; + case NEQ: + case NEQ | UNSMARK: + rv1 = rv1 != rv2; + break; + case LEQ: + rv1 = rv1 <= rv2; + break; + case GEQ: + rv1 = rv1 >= rv2; + break; + case LT: + rv1 = rv1 < rv2; + break; + case GT: + rv1 = rv1 > rv2; + break; + case LEQ | UNSMARK: + rv1 = (unsigned long)rv1 <= (unsigned long)rv2; + break; + case GEQ | UNSMARK: + rv1 = (unsigned long)rv1 >= (unsigned long)rv2; + break; + case LT | UNSMARK: + rv1 = (unsigned long)rv1 < (unsigned long)rv2; + break; + case GT | UNSMARK: + rv1 = (unsigned long)rv1 > (unsigned long)rv2; + break; + case LSH: + rv1 <<= rv2; + break; + case LSH | UNSMARK: + rv1 = (unsigned long) rv1 << rv2; + break; + case RSH: + rv1 >>= rv2; + break; + case RSH | UNSMARK: + rv1 = (unsigned long) rv1 >> rv2; + break; + case LAND: + rtype = UND; + if (v1.type == UND) + break; + if (rv1 != 0) + { + if (v2.type == UND) + break; + rv1 = rv2 != 0; + } + else + rv1 = 0; + rtype = SGN; + break; + case LOR: + rtype = UND; + if (v1.type == UND) + break; + if (rv1 == 0) + { + if (v2.type == UND) + break; + rv1 = rv2 != 0; + } + else + rv1 = 1; + rtype = SGN; + break; + case AND: + rv1 &= rv2; + break; + case STAR: + rv1 *= rv2; + break; + case PLUS: + rv1 += rv2; + break; + case MINUS: + rv1 -= rv2; + break; + case UMINUS: + if (v1.type == UND) + rtype = UND; + rv1 = -rv1; + break; + case OR: + rv1 |= rv2; + break; + case CIRC: + rv1 ^= rv2; + break; + case TILDE: + rv1 = ~rv1; + break; + case NOT: + rv1 = !rv1; + if (rtype != UND) + rtype = SGN; + break; + case SLASH: + if (rv2 == 0) + { + rtype = UND; + break; + } + if (rtype == UNS) + rv1 /= (unsigned long) rv2; + else + rv1 /= rv2; + break; + case PCT: + if (rv2 == 0) + { + rtype = UND; + break; + } + if (rtype == UNS) + rv1 %= (unsigned long) rv2; + else + rv1 %= rv2; + break; + case COLON: + if (op[-1] != QUEST) + error(ERROR, "Bad ?: in #if/endif"); + else + { + op--; + if ((--vp)->val == 0) + v1 = v2; + rtype = v1.type; + rv1 = v1.val; + } + break; + + case DEFINED: + case ARCHITECTURE: + break; + + default: + error(ERROR, "Eval botch (unknown operator)"); + return 1; + } +/*lint +e574 +e644 */ + v1.val = rv1; + v1.type = rtype; + *vp++ = v1; + } + return 0; +} + +struct value + tokval(Token * tp) +{ + struct value v; + Nlist *np; + int i, base; + unsigned long n; + uchar *p, c; + + v.type = SGN; + v.val = 0; + switch (tp->type) + { + + case NAME: + v.val = 0; + break; + + case NAME1: + if ((np = lookup(tp, 0)) != NULL && np->flag & (ISDEFINED | ISMAC)) + v.val = 1; + break; + + case NAME2: + if ((np = lookup(tp, 0)) != NULL && np->flag & (ISARCHITECTURE)) + v.val = 1; + break; + + case NUMBER: + n = 0; + base = 10; + p = tp->t; + c = p[tp->len]; + p[tp->len] = '\0'; + if (*p == '0') + { + base = 8; + if (p[1] == 'x' || p[1] == 'X') + { + base = 16; + p++; + } + p++; + } + for (;; p++) + { + if ((i = digit(*p)) < 0) + break; + if (i >= base) + error(WARNING, + "Bad digit in number %t", tp); + n *= base; + n += i; + } + if (n >= 0x80000000 && base != 10) + v.type = UNS; + for (; *p; p++) + { + if (*p == 'u' || *p == 'U') + v.type = UNS; + else + if (*p == 'l' || *p == 'L') + ; + else + { + error(ERROR, + "Bad number %t in #if/#elsif", tp); + break; + } + } + v.val = n; + tp->t[tp->len] = c; + break; + + case CCON: + n = 0; + p = tp->t; + if (*p == 'L') + { + p += 1; + error(WARNING, "Wide char constant value undefined"); + } + p += 1; + if (*p == '\\') + { + p += 1; + if ((i = digit(*p)) >= 0 && i <= 7) + { + n = i; + p += 1; + if ((i = digit(*p)) >= 0 && i <= 7) + { + p += 1; + n <<= 3; + n += i; + if ((i = digit(*p)) >= 0 && i <= 7) + { + p += 1; + n <<= 3; + n += i; + } + } + } + else + if (*p == 'x') + { + p += 1; + while ((i = digit(*p)) >= 0 && i <= 15) + { + p += 1; + n <<= 4; + n += i; + } + } + else + { + static char cvcon[] + = "b\bf\fn\nr\rt\tv\v''\"\"??\\\\"; + + for (i = 0; i < (int)sizeof(cvcon); i += 2) + { + if (*p == cvcon[i]) + { + n = cvcon[i + 1]; + break; + } + } + p += 1; + if (i >= (int)sizeof(cvcon)) + error(WARNING, + "Undefined escape in character constant"); + } + } + else + if (*p == '\'') + error(ERROR, "Empty character constant"); + else + n = *p++; + if (*p != '\'') + error(WARNING, "Multibyte character constant undefined"); + else + if (n > 127) + error(WARNING, "Character constant taken as not signed"); + v.val = n; + break; + + case STRING: + error(ERROR, "String in #if/#elsif"); + break; + } + return v; +} + +int + digit(int i) +{ + if ('0' <= i && i <= '9') + i -= '0'; + else + if ('a' <= i && i <= 'f') + i -= 'a' - 10; + else + if ('A' <= i && i <= 'F') + i -= 'A' - 10; + else + i = -1; + return i; +} diff --git a/idlc/source/preproc/include.c b/idlc/source/preproc/include.c new file mode 100644 index 000000000000..88a619905b64 --- /dev/null +++ b/idlc/source/preproc/include.c @@ -0,0 +1,256 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#if (defined(_WIN32) || defined(_MSDOS) || defined(__IBMC__)) +# include <io.h> +#else +# include <unistd.h> +#endif +#ifdef _MSC_VER +# define _POSIX_ +#endif +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> + +#ifdef __hpux +# define _HPUX_SOURCE +#endif +#ifdef SCO +#define _IBCS2 +#endif +#include <limits.h> + +#include "cpp.h" + +Includelist includelist[NINCLUDE]; +Wraplist wraplist[NINCLUDE]; + +void + doinclude(Tokenrow * trp, int depth, int import) +{ +#ifdef OS2 + char fname[_MAX_PATH], iname[_MAX_PATH]; +#else + char fname[PATH_MAX], iname[PATH_MAX]; +#endif + Includelist *ip; + int angled, len, fd, i; + + trp->tp += 1; + if (trp->tp >= trp->lp) + goto syntax; + if (trp->tp->type != STRING && trp->tp->type != LT) + { + len = trp->tp - trp->bp; + expandrow(trp, "<include>"); + trp->tp = trp->bp + len; + } + if (trp->tp->type == STRING) + { + len = trp->tp->len - 2; + if (len > (int)sizeof(fname) - 1) + len = sizeof(fname) - 1; + strncpy(fname, (char *) trp->tp->t + 1, len); + angled = 0; + } + else + if (trp->tp->type == LT) + { + len = 0; + trp->tp++; + while (trp->tp->type != GT) + { + if (trp->tp > trp->lp || len + trp->tp->len + 2 >= sizeof(fname)) + goto syntax; + strncpy(fname + len, (char *) trp->tp->t, trp->tp->len); + len += trp->tp->len; + trp->tp++; + } + angled = 1; + } + else + goto syntax; + trp->tp += 2; + if (trp->tp < trp->lp || len == 0) + goto syntax; + fname[len] = '\0'; + if (fname[0] == '/') + { + fd = open(fname, O_RDONLY); + strcpy(iname, fname); + } + else + for (fd = -1, i = (depth < 0) ? (NINCLUDE - 1) : (depth - 1); i >= 0; i--) + { + ip = &includelist[i]; + if (ip->file == NULL || ip->deleted || (angled && ip->always == 0)) + continue; + if (strlen(fname) + strlen(ip->file) + 2 > sizeof(iname)) + continue; + strcpy(iname, ip->file); + strcat(iname, "/"); + strcat(iname, fname); + if ((fd = open(iname, O_RDONLY)) >= 0) + break; + } + if (fd >= 0) + { + if (++incdepth > NINC ) + error(FATAL, "#%s too deeply nested", import ? "import" : "include"); + if (Xflag) + genimport(fname, angled, iname, import); + if (Iflag) + error(INFO, "Open %s file [%s]", import ? "import" : "include", iname ); + + for (i = NINCLUDE - 1; i >= 0; i--) + { + if ((wraplist[i].file != NULL) && + (strncmp(wraplist[i].file, iname, strlen(wraplist[i].file)) == 0)) + break; + } + + setsource((char *) newstring((uchar *) iname, strlen(iname), 0), i, fd, NULL, (i >= 0) ? 1 : 0); + + if (!Pflag) + genline(); + } + else + { + trp->tp = trp->bp + 2; + error(ERROR, "Could not find %s file %r", import ? "import" : "include", trp); + } + return; +syntax: + error(ERROR, "Syntax error in #%s", import ? "import" : "include"); + return; +} + +/* + * Generate a line directive for cursource + */ +void + genline(void) +{ + static Token ta = {UNCLASS, 0, 0, 0, NULL }; + static Tokenrow tr = {&ta, &ta, &ta + 1, 1}; + uchar *p; + + ta.t = p = (uchar *) outptr; + strcpy((char *) p, "#line "); + p += sizeof("#line ") - 1; + p = (uchar *) outnum((char *) p, cursource->line); + *p++ = ' '; + *p++ = '"'; + if (cursource->filename[0] != '/' && wd[0]) + { + strcpy((char *) p, wd); + p += strlen(wd); + *p++ = '/'; + } + strcpy((char *) p, cursource->filename); + p += strlen((char *) p); + *p++ = '"'; + *p++ = '\n'; + ta.len = (char *) p - outptr; + outptr = (char *) p; + tr.tp = tr.bp; + puttokens(&tr); +} + +/* + * Generate a pragma import/include directive + */ +void + genimport(char *fname, int angled, char *iname, int import) +{ + static Token ta = {UNCLASS, 0, 0, 0, NULL }; + static Tokenrow tr = {&ta, &ta, &ta + 1, 1}; + uchar *p; + + ta.t = p = (uchar *) outptr; + + if (import) + strcpy((char *) p, "#pragma import"); + else + strcpy((char *) p, "#pragma include"); + + p += strlen((char *) p); + + *p++ = '('; + + *p++ = angled ? '<' : '"'; + strcpy((char *) p, fname); + p += strlen(fname); + *p++ = angled ? '>' : '"'; + + *p++ = ','; + + *p++ = '"'; + strcpy((char *) p, iname); + p += strlen(iname); + *p++ = '"'; + + *p++ = ')'; + *p++ = '\n'; + + ta.len = (char *) p - outptr; + outptr = (char *) p; + tr.tp = tr.bp; + puttokens(&tr); +} + +/* + * Generate a extern C directive + */ +void + genwrap(int end) +{ + static Token ta = {UNCLASS, 0, 0, 0, NULL}; + static Tokenrow tr = {&ta, &ta, &ta + 1, 1}; + uchar *p; + + if (Cplusplus) + { + ta.t = p = (uchar *) outptr; + + if (! end) + strcpy((char *) p, "extern \"C\" {"); + else + strcpy((char *) p, "}"); + + p += strlen((char *) p); + + *p++ = '\n'; + + ta.len = (char *) p - outptr; + outptr = (char *) p; + tr.tp = tr.bp; + puttokens(&tr); + } +} + diff --git a/idlc/source/preproc/lex.c b/idlc/source/preproc/lex.c new file mode 100644 index 000000000000..fd6d00792984 --- /dev/null +++ b/idlc/source/preproc/lex.c @@ -0,0 +1,695 @@ +/************************************************************************* + * + * 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 <stdio.h> +#include <stdlib.h> +#include <string.h> +#if (defined(_WIN32) || defined(_MSDOS) || defined(__IBMC__)) +#include <io.h> +#else +#include <unistd.h> +#endif +#include "cpp.h" + +/* + * lexical FSM encoding + * when in state state, and one of the characters + * in ch arrives, enter nextstate. + * States >= S_SELF are either final, or at least require special action. + * In 'fsm' there is a line for each state X charset X nextstate. + * List chars that overwrite previous entries later (e.g. C_ALPH + * can be overridden by '_' by a later entry; and C_XX is the + * the universal set, and should always be first. + * States above S_SELF are represented in the big table as negative values. + * S_SELF and S_SELFB encode the resulting token type in the upper bits. + * These actions differ in that S_SELF doesn't have a lookahead char, + * S_SELFB does. + * + * The encoding is blown out into a big table for time-efficiency. + * Entries have + * nextstate: 6 bits; ?\ marker: 1 bit; tokentype: 9 bits. + */ + +#define MAXSTATE 32 +#define ACT(tok,act) ((tok<<7)+act) +#define QBSBIT 0100 +#define GETACT(st) ((st>>7)&0x1ff) + +/* character classes */ +#define C_WS 1 +#define C_ALPH 2 +#define C_NUM 3 +#define C_EOF 4 +#define C_XX 5 + +enum state +{ + START = 0, NUM1, NUM2, NUM3, ID1, ST1, ST2, ST3, COM1, COM2, COM3, COM4, + CC1, CC2, WS1, PLUS1, MINUS1, STAR1, SLASH1, PCT1, SHARP1, + CIRC1, GT1, GT2, LT1, LT2, OR1, AND1, ASG1, NOT1, DOTS1, + S_SELF = MAXSTATE, S_SELFB, S_EOF, S_NL, S_EOFSTR, + S_STNL, S_COMNL, S_EOFCOM, S_COMMENT, S_EOB, S_WS, S_NAME +}; + +int tottok; +int tokkind[256]; +struct fsm +{ + int state; /* if in this state */ + uchar ch[4]; /* and see one of these characters */ + int nextstate; /* enter this state if +ve */ +}; + + /*const*/ struct fsm fsm[] = { + /* start state */ + { START, {C_XX}, ACT(UNCLASS, S_SELF) }, + { START, {' ', '\t', '\v'}, WS1 }, + { START, {C_NUM}, NUM1 }, + { START, {'.'}, NUM3 }, + { START, {C_ALPH}, ID1 }, + { START, {'L'}, ST1 }, + { START, {'"'}, ST2 }, + { START, {'\''}, CC1 }, + { START, {'/'}, COM1 }, + { START, {EOFC}, S_EOF }, + { START, {'\n'}, S_NL }, + { START, {'-'}, MINUS1 }, + { START, {'+'}, PLUS1 }, + { START, {'<'}, LT1 }, + { START, {'>'}, GT1 }, + { START, {'='}, ASG1 }, + { START, {'!'}, NOT1 }, + { START, {'&'}, AND1 }, + { START, {'|'}, OR1 }, + { START, {'#'}, SHARP1 }, + { START, {'%'}, PCT1 }, + { START, {'['}, ACT(SBRA, S_SELF) }, + { START, {']'}, ACT(SKET, S_SELF) }, + { START, {'('}, ACT(LP, S_SELF) }, + { START, {')'}, ACT(RP, S_SELF) }, + { START, {'*'}, STAR1 }, + { START, {','}, ACT(COMMA, S_SELF) }, + { START, {'?'}, ACT(QUEST, S_SELF) }, + { START, {':'}, ACT(COLON, S_SELF) }, + { START, {';'}, ACT(SEMIC, S_SELF) }, + { START, {'{'}, ACT(CBRA, S_SELF) }, + { START, {'}'}, ACT(CKET, S_SELF) }, + { START, {'~'}, ACT(TILDE, S_SELF) }, + { START, {'^'}, CIRC1 }, + + /* saw a digit */ + { NUM1, {C_XX}, ACT(NUMBER, S_SELFB) }, + { NUM1, {C_NUM, C_ALPH, '.'}, NUM1 }, + { NUM1, {'E', 'e'}, NUM2 }, + { NUM1, {'_'}, ACT(NUMBER, S_SELFB) }, + + /* saw possible start of exponent, digits-e */ + { NUM2, {C_XX}, ACT(NUMBER, S_SELFB) }, + { NUM2, {'+', '-'}, NUM1 }, + { NUM2, {C_NUM, C_ALPH}, NUM1 }, + { NUM2, {'_'}, ACT(NUMBER, S_SELFB) }, + + /* saw a '.', which could be a number or an operator */ + { NUM3, {C_XX}, ACT(DOT, S_SELFB) }, + { NUM3, {'.'}, DOTS1 }, + { NUM3, {C_NUM}, NUM1 }, + + { DOTS1, {C_XX}, ACT(UNCLASS, S_SELFB) }, + { DOTS1, {C_NUM}, NUM1 }, + { DOTS1, {'.'}, ACT(ELLIPS, S_SELF) }, + + /* saw a letter or _ */ + { ID1, {C_XX}, ACT(NAME, S_NAME) }, + { ID1, {C_ALPH, C_NUM}, ID1 }, + + /* saw L (start of wide string?) */ + { ST1, {C_XX}, ACT(NAME, S_NAME) }, + { ST1, {C_ALPH, C_NUM}, ID1 }, + { ST1, {'"'}, ST2 }, + { ST1, {'\''}, CC1 }, + + /* saw " beginning string */ + { ST2, {C_XX}, ST2 }, + { ST2, {'"'}, ACT(STRING, S_SELF) }, + { ST2, {'\\'}, ST3 }, + { ST2, {'\n'}, S_STNL }, + { ST2, {EOFC}, S_EOFSTR }, + + /* saw \ in string */ + { ST3, {C_XX}, ST2 }, + { ST3, {'\n'}, S_STNL }, + { ST3, {EOFC}, S_EOFSTR }, + + /* saw ' beginning character const */ + { CC1, {C_XX}, CC1 }, + { CC1, {'\''}, ACT(CCON, S_SELF) }, + { CC1, {'\\'}, CC2 }, + { CC1, {'\n'}, S_STNL }, + { CC1, {EOFC}, S_EOFSTR }, + + /* saw \ in ccon */ + { CC2, {C_XX}, CC1 }, + { CC2, {'\n'}, S_STNL }, + { CC2, {EOFC}, S_EOFSTR }, + + /* saw /, perhaps start of comment */ + { COM1, {C_XX}, ACT(SLASH, S_SELFB) }, + { COM1, {'='}, ACT(ASSLASH, S_SELF) }, + { COM1, {'*'}, COM2 }, + { COM1, {'/'}, COM4 }, + + /* saw / followed by *, start of comment */ + { COM2, {C_XX}, COM2 }, + { COM2, {'\n'}, S_COMNL }, + { COM2, {'*'}, COM3 }, + { COM2, {EOFC}, S_EOFCOM }, + + /* saw the * possibly ending a comment */ + { COM3, {C_XX}, COM2 }, + { COM3, {'\n'}, S_COMNL }, + { COM3, {'*'}, COM3 }, + { COM3, {'/'}, S_COMMENT }, + + /* // comment */ + { COM4, {C_XX}, COM4 }, + { COM4, {'\n'}, S_COMMENT }, + /* { COM4, {'\n'}, S_NL }, */ + { COM4, {EOFC}, S_EOFCOM }, + + /* saw white space, eat it up */ + { WS1, {C_XX}, S_WS }, + { WS1, {'\t', '\v', ' '}, WS1 }, + + /* saw -, check --, -=, -> */ + { MINUS1, {C_XX}, ACT(MINUS, S_SELFB) }, + { MINUS1, {'-'}, ACT(MMINUS, S_SELF) }, + { MINUS1, {'='}, ACT(ASMINUS, S_SELF) }, + { MINUS1, {'>'}, ACT(ARROW, S_SELF) }, + + /* saw +, check ++, += */ + { PLUS1, {C_XX}, ACT(PLUS, S_SELFB) }, + { PLUS1, {'+'}, ACT(PPLUS, S_SELF) }, + { PLUS1, {'='}, ACT(ASPLUS, S_SELF) }, + + /* saw <, check <<, <<=, <= */ + { LT1, {C_XX}, ACT(LT, S_SELFB) }, + { LT1, {'<'}, LT2 }, + { LT1, {'='}, ACT(LEQ, S_SELF) }, + { LT2, {C_XX}, ACT(LSH, S_SELFB) }, + { LT2, {'='}, ACT(ASLSH, S_SELF) }, + + /* saw >, check >>, >>=, >= */ + { GT1, {C_XX}, ACT(GT, S_SELFB) }, + { GT1, {'>'}, GT2 }, + { GT1, {'='}, ACT(GEQ, S_SELF) }, + { GT2, {C_XX}, ACT(RSH, S_SELFB) }, + { GT2, {'='}, ACT(ASRSH, S_SELF) }, + + /* = */ + { ASG1, {C_XX}, ACT(ASGN, S_SELFB) }, + { ASG1, {'='}, ACT(EQ, S_SELF) }, + + /* ! */ + { NOT1, {C_XX}, ACT(NOT, S_SELFB) }, + { NOT1, {'='}, ACT(NEQ, S_SELF) }, + + /* & */ + { AND1, {C_XX}, ACT(AND, S_SELFB) }, + { AND1, {'&'}, ACT(LAND, S_SELF) }, + { AND1, {'='}, ACT(ASAND, S_SELF) }, + + /* | */ + { OR1, {C_XX}, ACT(OR, S_SELFB) }, + { OR1, {'|'}, ACT(LOR, S_SELF) }, + { OR1, {'='}, ACT(ASOR, S_SELF) }, + + /* # */ + { SHARP1, {C_XX}, ACT(SHARP, S_SELFB) }, + { SHARP1, {'#'}, ACT(DSHARP, S_SELF) }, + + /* % */ + { PCT1, {C_XX}, ACT(PCT, S_SELFB) }, + { PCT1, {'='}, ACT(ASPCT, S_SELF) }, + + /* * */ + { STAR1, {C_XX}, ACT(STAR, S_SELFB) }, + { STAR1, {'='}, ACT(ASSTAR, S_SELF) }, + + /* ^ */ + { CIRC1, {C_XX}, ACT(CIRC, S_SELFB) }, + { CIRC1, {'='}, ACT(ASCIRC, S_SELF) }, + + { -1, {'\0'}, S_SELF } +}; + +/* first index is char, second is state */ +/* increase #states to power of 2 to encourage use of shift */ +short bigfsm[256][MAXSTATE]; + +void + expandlex(void) +{ + /* const */ struct fsm *fp; + int i, j, nstate; + + for (fp = fsm; fp->state >= 0; fp++) + { + for (i = 0; fp->ch[i]; i++) + { + nstate = fp->nextstate; + if (nstate >= S_SELF) + nstate = ~nstate; + switch (fp->ch[i]) + { + + case C_XX: /* random characters */ + for (j = 0; j < 256; j++) + bigfsm[j][fp->state] = (short) nstate; + continue; + case C_ALPH: + for (j = 0; j <= 256; j++) + if (('a' <= j && j <= 'z') || ('A' <= j && j <= 'Z') + || j == '_') + bigfsm[j][fp->state] = (short) nstate; + continue; + case C_NUM: + for (j = '0'; j <= '9'; j++) + bigfsm[j][fp->state] = (short) nstate; + continue; + default: + bigfsm[fp->ch[i]][fp->state] = (short) nstate; + } + } + } + + /* + * install special cases for ? (trigraphs), \ (splicing), runes, and + * EOB + */ + for (i = 0; i < MAXSTATE; i++) + { + for (j = 0; j < 0xFF; j++) + if (j == '?' || j == '\\' || j == '\n' || j == '\r') + { + if (bigfsm[j][i] > 0) + bigfsm[j][i] = ~bigfsm[j][i]; + bigfsm[j][i] &= ~QBSBIT; + } + bigfsm[EOB][i] = ~S_EOB; + if (bigfsm[EOFC][i] >= 0) + bigfsm[EOFC][i] = ~S_EOF; + } +} + +/* + * fill in a row of tokens from input, terminated by NL or END + * First token is put at trp->lp. + * Reset is non-zero when the input buffer can be "rewound." + * The value is a flag indicating that possible macros have + * been seen in the row. + */ +int + gettokens(Tokenrow * trp, int reset) +{ + register int c, state, oldstate; + register uchar *ip; + register Token *tp, *maxp; + int runelen; + Source *s = cursource; + int nmac = 0; + + tp = trp->lp; + ip = s->inp; + if (reset) + { + s->lineinc = 0; + if (ip >= s->inl) + { /* nothing in buffer */ + s->inl = s->inb; + fillbuf(s); + ip = s->inp = s->inb; + } + else + if (ip >= s->inb + (3 * INS / 4)) + { + memmove(s->inb, ip, 4 + s->inl - ip); + s->inl = s->inb + (s->inl - ip); + ip = s->inp = s->inb; + } + } + maxp = &trp->bp[trp->max]; + runelen = 1; + for (;;) + { +continue2: + if (tp >= maxp) + { + trp->lp = tp; + tp = growtokenrow(trp); + maxp = &trp->bp[trp->max]; + } + tp->type = UNCLASS; + tp->t = ip; + tp->wslen = 0; + tp->flag = 0; + state = START; + for (;;) + { + oldstate = state; + + c = *ip; + + if ((state = bigfsm[c][state]) >= 0) + { + ip += runelen; + runelen = 1; + continue; + } + state = ~state; + reswitch: + switch (state & 0177) + { + case S_SELF: + ip += runelen; + runelen = 1; + case S_SELFB: + tp->type = (unsigned char) GETACT(state); + tp->len = ip - tp->t; + tp++; + goto continue2; + + case S_NAME: /* like S_SELFB but with nmac check */ + tp->type = NAME; + tp->len = ip - tp->t; + nmac |= quicklook(tp->t[0], tp->len > 1 ? tp->t[1] : 0); + tp++; + goto continue2; + + case S_WS: + tp->wslen = ip - tp->t; + tp->t = ip; + state = START; + continue; + + default: + if ((state & QBSBIT) == 0) + { + ip += runelen; + runelen = 1; + continue; + } + state &= ~QBSBIT; + s->inp = ip; + + if (c == '\n') + { + while (s->inp + 1 >= s->inl && fillbuf(s) != EOF); + + if (s->inp[1] == '\r') + { + memmove(s->inp + 1, s->inp + 2, s->inl - s->inp + 2); + s->inl -= 1; + } + + goto reswitch; + } + + if (c == '\r') + { + while (s->inp + 1 >= s->inl && fillbuf(s) != EOF); + + if (s->inp[1] == '\n') + { + memmove(s->inp, s->inp + 1, s->inl - s->inp + 1); + s->inl -= 1; + } + else + *s->inp = '\n'; + + state = oldstate; + continue; + } + + if (c == '?') + { /* check trigraph */ + if (trigraph(s)) + { + state = oldstate; + continue; + } + goto reswitch; + } + if (c == '\\') + { /* line-folding */ + if (foldline(s)) + { + s->lineinc++; + state = oldstate; + continue; + } + goto reswitch; + } + error(WARNING, "Lexical botch in cpp"); + ip += runelen; + runelen = 1; + continue; + + case S_EOB: + s->inp = ip; + fillbuf(cursource); + state = oldstate; + continue; + + case S_EOF: + tp->type = END; + tp->len = 0; + s->inp = ip; + if (tp != trp->bp && (tp - 1)->type != NL && cursource->fd != -1) + error(WARNING, "No newline at end of file"); + trp->lp = tp + 1; + return nmac; + + case S_STNL: + error(ERROR, "Unterminated string or char const"); + case S_NL: + tp->t = ip; + tp->type = NL; + tp->len = 1; + tp->wslen = 0; + s->lineinc++; + s->inp = ip + 1; + trp->lp = tp + 1; + return nmac; + + case S_EOFSTR: + error(FATAL, "EOF in string or char constant"); + break; + + case S_COMNL: + s->lineinc++; + state = COM2; + ip += runelen; + runelen = 1; + continue; + + case S_EOFCOM: + error(WARNING, "EOF inside comment"); + --ip; + case S_COMMENT: + if (!Cflag) + { + tp->t = ++ip; + tp->t[-1] = ' '; + tp->wslen = 1; + state = START; + continue; + } + else + { + runelen = 1; + /* s->lineinc = 0; */ + tp->type = COMMENT; + tp->flag |= XTWS; + } + } + break; + } + ip += runelen; + runelen = 1; + tp->len = ip - tp->t; + tp++; + } +} + +/* have seen ?; handle the trigraph it starts (if any) else 0 */ +int + trigraph(Source * s) +{ + uchar c; + + while (s->inp + 2 >= s->inl && fillbuf(s) != EOF); + ; + if (s->inp[1] != '?') + return 0; + c = 0; + switch (s->inp[2]) + { + case '=': + c = '#'; + break; + case '(': + c = '['; + break; + case '/': + c = '\\'; + break; + case ')': + c = ']'; + break; + case '\'': + c = '^'; + break; + case '<': + c = '{'; + break; + case '!': + c = '|'; + break; + case '>': + c = '}'; + break; + case '-': + c = '~'; + break; + } + if (c) + { + *s->inp = c; + memmove(s->inp + 1, s->inp + 3, s->inl - s->inp + 2); + s->inl -= 2; + } + return c; +} + +int + foldline(Source * s) +{ + int n = 1; + + while (s->inp + 2 >= s->inl && fillbuf(s) != EOF); + + /* skip DOS line ends */ + if (((s->inp[n] == '\r') && (s->inp[n+1] == '\n')) || + ((s->inp[n] == '\n') && (s->inp[n+1] == '\r'))) + n++; + + if ((s->inp[n] == '\n') || (s->inp[n] == '\r')) + { + memmove(s->inp, s->inp + n + 1, s->inl - s->inp + n + 2); + s->inl -= n + 1; + return 1; + } + return 0; +} + +int + fillbuf(Source * s) +{ + int n; + + if (s->fd < 0 || (n = read(s->fd, (char *) s->inl, INS / 8)) <= 0) + n = 0; + s->inl += n; + s->inl[0] = s->inl[1] = s->inl[2] = s->inl[3] = EOB; + if (n == 0) + { + s->inl[0] = s->inl[1] = s->inl[2] = s->inl[3] = EOFC; + return EOF; + } + return 0; +} + +/* + * Push down to new source of characters. + * If fd>0 and str==NULL, then from a file `name'; + * if fd==-1 and str, then from the string. + */ +Source * + setsource(char *name, int path, int fd, char *str, int wrap) +{ + Source *s = new(Source); + int len; + + s->line = 1; + s->lineinc = 0; + s->fd = fd; + s->filename = name; + s->next = cursource; + s->ifdepth = 0; + s->pathdepth = path; + s->wrap = wrap; + + cursource = s; + + if (s->wrap) + genwrap(0); + + /* slop at right for EOB */ + if (str) + { + len = strlen(str); + s->inb = domalloc(len + 4); + s->inp = s->inb; + strncpy((char *) s->inp, str, len); + } + else + { + s->inb = domalloc(INS + 4); + s->inp = s->inb; + len = 0; + } + s->inl = s->inp + len; + s->inl[0] = s->inl[1] = EOB; + + return s; +} + +void + unsetsource(void) +{ + Source *s = cursource; + + if (s->wrap) + genwrap(1); + + if (s->fd >= 0) + { + close(s->fd); + dofree(s->inb); + } + cursource = s->next; + dofree(s); +} diff --git a/idlc/source/preproc/macro.c b/idlc/source/preproc/macro.c new file mode 100644 index 000000000000..7f0697994c4c --- /dev/null +++ b/idlc/source/preproc/macro.c @@ -0,0 +1,700 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ +#ifdef _MSC_VER +# define _POSIX_ +#endif +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#ifdef __hpux +# define _HPUX_SOURCE +#endif +#ifdef SCO +# define _IBCS2 +#endif +#include <limits.h> + +#include "cpp.h" + +#define NCONCAT 16384 + +/* + * do a macro definition. tp points to the name being defined in the line + */ +void + dodefine(Tokenrow * trp) +{ + Token *tp; + Nlist *np; + Source *s; + Tokenrow *def, *args; +#ifdef OS2 + static uchar location[(_MAX_PATH + 8) * NINC], *cp; +#else + static uchar location[(PATH_MAX + 8) * NINC], *cp; +#endif + tp = trp->tp + 1; + if (tp >= trp->lp || tp->type != NAME) + { + error(ERROR, "#defined token is not a name"); + return; + } + np = lookup(tp, 1); + if (np->flag & ISUNCHANGE) + { + error(ERROR, "#defined token %t can't be redefined", tp); + return; + } + /* collect arguments */ + tp += 1; + args = NULL; + if (tp < trp->lp && tp->type == LP && tp->wslen == 0) + { + /* macro with args */ + int narg = 0; + + tp += 1; + args = new(Tokenrow); + maketokenrow(2, args); + if (tp->type != RP) + { + int err = 0; + + for (;;) + { + Token *atp; + + if (tp->type != NAME) + { + err++; + break; + } + if (narg >= args->max) + growtokenrow(args); + for (atp = args->bp; atp < args->lp; atp++) + if (atp->len == tp->len + && strncmp((char *) atp->t, (char *) tp->t, tp->len) == 0) + error(ERROR, "Duplicate macro argument"); + *args->lp++ = *tp; + narg++; + tp += 1; + if (tp->type == RP) + break; + if (tp->type != COMMA) + { + err++; + break; + } + tp += 1; + } + if (err) + { + error(ERROR, "Syntax error in macro parameters"); + return; + } + } + tp += 1; + } + trp->tp = tp; + if (((trp->lp) - 1)->type == NL) + trp->lp -= 1; + def = normtokenrow(trp); + if (np->flag & ISDEFINED) + { + if (comparetokens(def, np->vp) + || (np->ap == NULL) != (args == NULL) + || (np->ap && comparetokens(args, np->ap))) + error(ERROR, "Macro redefinition of %t (already defined at %s)", trp->bp + 2, np->loc); + } + if (args) + { + Tokenrow *tap; + + tap = normtokenrow(args); + dofree(args->bp); + args = tap; + } + np->ap = args; + np->vp = def; + np->flag |= ISDEFINED; + + /* build location string of macro definition */ + for (cp = location, s = cursource; s; s = s->next) + if (*s->filename) + { + if (cp != location) + *cp++ = ' '; + sprintf((char *)cp, "%s:%d", s->filename, s->line); + cp += strlen((char *)cp); + } + + np->loc = newstring(location, strlen((char *)location), 0); + + if (Mflag) + { + if (np->ap) + error(INFO, "Macro definition of %s(%r) [%r]", np->name, np->ap, np->vp); + else + error(INFO, "Macro definition of %s [%r]", np->name, np->vp); + } +} + +/* + * Definition received via -D or -U + */ +void + doadefine(Tokenrow * trp, int type) +{ + Nlist *np; + static uchar onestr[2] = "1"; + static Token onetoken[1] = {{NUMBER, 0, 0, 1, onestr}}; + static Tokenrow onetr = {onetoken, onetoken, onetoken + 1, 1}; + + trp->tp = trp->bp; + if (type == 'U') + { + if (trp->lp - trp->tp != 2 || trp->tp->type != NAME) + goto syntax; + if ((np = lookup(trp->tp, 0)) == NULL) + return; + np->flag &= ~ISDEFINED; + return; + } + + if (type == 'A') + { + if (trp->tp >= trp->lp || trp->tp->type != NAME) + goto syntax; + trp->tp->type = ARCHITECTURE; + np = lookup(trp->tp, 1); + np->flag |= ISARCHITECTURE; + trp->tp += 1; + if (trp->tp >= trp->lp || trp->tp->type == END) + { + np->vp = &onetr; + return; + } + else + error(FATAL, "Illegal -A argument %r", trp); + } + + if (trp->tp >= trp->lp || trp->tp->type != NAME) + goto syntax; + np = lookup(trp->tp, 1); + np->flag |= ISDEFINED; + trp->tp += 1; + if (trp->tp >= trp->lp || trp->tp->type == END) + { + np->vp = &onetr; + return; + } + if (trp->tp->type != ASGN) + goto syntax; + trp->tp += 1; + if ((trp->lp - 1)->type == END) + trp->lp -= 1; + np->vp = normtokenrow(trp); + return; +syntax: + error(FATAL, "Illegal -D or -U argument %r", trp); +} + +/* + * Do macro expansion in a row of tokens. + * Flag is NULL if more input can be gathered. + */ +void + expandrow(Tokenrow * trp, char *flag) +{ + Token *tp; + Nlist *np; + + if (flag) + setsource(flag, -1, -1, "", 0); + for (tp = trp->tp; tp < trp->lp;) + { + if (tp->type != NAME + || quicklook(tp->t[0], tp->len > 1 ? tp->t[1] : 0) == 0 + || (np = lookup(tp, 0)) == NULL + || (np->flag & (ISDEFINED | ISMAC)) == 0 + || (np->flag & ISACTIVE) != 0) + { + tp++; + continue; + } + trp->tp = tp; + if (np->val == KDEFINED) + { + tp->type = DEFINED; + if ((tp + 1) < trp->lp && (tp + 1)->type == NAME) + (tp + 1)->type = NAME1; + else + if ((tp + 3) < trp->lp && (tp + 1)->type == LP + && (tp + 2)->type == NAME && (tp + 3)->type == RP) + (tp + 2)->type = NAME1; + else + error(ERROR, "Incorrect syntax for `defined'"); + tp++; + continue; + } + else + if (np->val == KMACHINE) + { + if (((tp - 1) >= trp->bp) && ((tp - 1)->type == SHARP)) + { + tp->type = ARCHITECTURE; + if ((tp + 1) < trp->lp && (tp + 1)->type == NAME) + (tp + 1)->type = NAME2; + else + if ((tp + 3) < trp->lp && (tp + 1)->type == LP + && (tp + 2)->type == NAME && (tp + 3)->type == RP) + (tp + 2)->type = NAME2; + else + error(ERROR, "Incorrect syntax for `#machine'"); + } + tp++; + continue; + } + + if (np->flag & ISMAC) + builtin(trp, np->val); + else + expand(trp, np); + tp = trp->tp; + } + if (flag) + unsetsource(); +} + +/* + * Expand the macro whose name is np, at token trp->tp, in the tokenrow. + * Return trp->tp at the first token next to be expanded + * (ordinarily the beginning of the expansion) + */ +void + expand(Tokenrow * trp, Nlist * np) +{ + Tokenrow ntr; + int ntokc, narg, i; + Tokenrow *atr[NARG + 1]; + + if (Mflag == 2) + { + if (np->ap) + error(INFO, "Macro expansion of %t with %s(%r)", trp->tp, np->name, np->ap); + else + error(INFO, "Macro expansion of %t with %s", trp->tp, np->name); + } + + copytokenrow(&ntr, np->vp); /* copy macro value */ + if (np->ap == NULL) /* parameterless */ + ntokc = 1; + else + { + ntokc = gatherargs(trp, atr, &narg); + if (narg < 0) + { /* not actually a call (no '(') */ + trp->tp++; + return; + } + if (narg != rowlen(np->ap)) + { + error(ERROR, "Disagreement in number of macro arguments"); + trp->tp += ntokc; + return; + } + substargs(np, &ntr, atr); /* put args into replacement */ + for (i = 0; i < narg; i++) + { + dofree(atr[i]->bp); + dofree(atr[i]); + } + } + + np->flag |= ISACTIVE; + + doconcat(&ntr); /* execute ## operators */ + ntr.tp = ntr.bp; + makespace(&ntr, trp->tp); + expandrow(&ntr, "<expand>"); + insertrow(trp, ntokc, &ntr); + dofree(ntr.bp); + + np->flag &= ~ISACTIVE; + + return; +} + +/* + * Gather an arglist, starting in trp with tp pointing at the macro name. + * Return total number of tokens passed, stash number of args found. + * trp->tp is not changed relative to the tokenrow. + */ +int + gatherargs(Tokenrow * trp, Tokenrow ** atr, int *narg) +{ + int parens = 1; + int ntok = 0; + Token *bp, *lp; + Tokenrow ttr; + int ntokp; + int needspace; + + *narg = -1; /* means that there is no macro + * call */ + /* look for the ( */ + for (;;) + { + trp->tp++; + ntok++; + if (trp->tp >= trp->lp) + { + gettokens(trp, 0); + if ((trp->lp - 1)->type == END) + { + trp->lp -= 1; + trp->tp -= ntok; + return ntok; + } + } + if (trp->tp->type == LP) + break; + if (trp->tp->type != NL) + return ntok; + } + *narg = 0; + ntok++; + ntokp = ntok; + trp->tp++; + /* search for the terminating ), possibly extending the row */ + needspace = 0; + while (parens > 0) + { + if (trp->tp >= trp->lp) + gettokens(trp, 0); + if (needspace) + { + needspace = 0; + /* makespace(trp); [rh] */ + } + if (trp->tp->type == END) + { + trp->lp -= 1; + trp->tp -= ntok; + error(ERROR, "EOF in macro arglist"); + return ntok; + } + if (trp->tp->type == NL) + { + trp->tp += 1; + adjustrow(trp, -1); + trp->tp -= 1; + /* makespace(trp); [rh] */ + needspace = 1; + continue; + } + if (trp->tp->type == LP) + parens++; + else + if (trp->tp->type == RP) + parens--; + trp->tp++; + ntok++; + } + trp->tp -= ntok; + /* Now trp->tp won't move underneath us */ + lp = bp = trp->tp + ntokp; + for (; parens >= 0; lp++) + { + if (lp->type == LP) + { + parens++; + continue; + } + if (lp->type == RP) + parens--; + if (lp->type == DSHARP) + lp->type = DSHARP1; /* ## not special in arg */ + if ((lp->type == COMMA && parens == 0) + || (parens < 0 && (lp - 1)->type != LP)) + { + if (*narg >= NARG - 1) + error(FATAL, "Sorry, too many macro arguments"); + ttr.bp = ttr.tp = bp; + ttr.lp = lp; + atr[(*narg)++] = normtokenrow(&ttr); + bp = lp + 1; + } + } + return ntok; +} + +/* + * substitute the argument list into the replacement string + * This would be simple except for ## and # + */ +void + substargs(Nlist * np, Tokenrow * rtr, Tokenrow ** atr) +{ + Tokenrow tatr; + Token *tp; + int ntok, argno; + + for (rtr->tp = rtr->bp; rtr->tp < rtr->lp;) + { + if (rtr->tp->type == SHARP) + { /* string operator */ + tp = rtr->tp; + rtr->tp += 1; + if ((argno = lookuparg(np, rtr->tp)) < 0) + { + error(ERROR, "# not followed by macro parameter"); + continue; + } + ntok = 1 + (rtr->tp - tp); + rtr->tp = tp; + insertrow(rtr, ntok, stringify(atr[argno])); + continue; + } + if (rtr->tp->type == NAME + && (argno = lookuparg(np, rtr->tp)) >= 0) + { + if (((rtr->tp + 1) < rtr->lp && (rtr->tp + 1)->type == DSHARP) + || (rtr->tp != rtr->bp && (rtr->tp - 1)->type == DSHARP)) + { + copytokenrow(&tatr, atr[argno]); + makespace(&tatr, rtr->tp); + insertrow(rtr, 1, &tatr); + dofree(tatr.bp); + } + else + { + copytokenrow(&tatr, atr[argno]); + makespace(&tatr, rtr->tp); + expandrow(&tatr, "<macro>"); + insertrow(rtr, 1, &tatr); + dofree(tatr.bp); + } + continue; + } + rtr->tp++; + } +} + +/* + * Evaluate the ## operators in a tokenrow + */ +void + doconcat(Tokenrow * trp) +{ + Token *ltp, *ntp; + Tokenrow ntr; + int len; + + for (trp->tp = trp->bp; trp->tp < trp->lp; trp->tp++) + { + if (trp->tp->type == DSHARP1) + trp->tp->type = DSHARP; + else + if (trp->tp->type == DSHARP) + { + int i; + char tt[NCONCAT]; + + ltp = trp->tp - 1; + ntp = trp->tp + 1; + + if (ltp < trp->bp || ntp >= trp->lp) + { + error(ERROR, "## occurs at border of replacement"); + continue; + } + + ntp = ltp; + i = 1; + len = 0; + + do + { + if (len + ntp->len + ntp->wslen > sizeof(tt)) + { + error(ERROR, "## string concatination buffer overrun"); + break; + } + + strncpy((char *) tt + len, (char *) ntp->t - ntp->wslen, + ntp->len + ntp->wslen); + len += ntp->len + ntp->wslen; + + ntp = trp->tp + i; + i++; + } + while (ntp < trp->lp); + + tt[len] = '\0'; + setsource("<##>", -1, -1, tt, 0); + maketokenrow(3, &ntr); + gettokens(&ntr, 1); + unsetsource(); + if (ntr.bp->type == UNCLASS) + error(WARNING, "Bad token %r produced by ##", &ntr); + doconcat(&ntr); + trp->tp = ltp; + makespace(&ntr, ltp); + insertrow(trp, ntp - ltp, &ntr); + dofree(ntr.bp); + trp->tp--; + } + } +} + +/* + * tp is a potential parameter name of macro mac; + * look it up in mac's arglist, and if found, return the + * corresponding index in the argname array. Return -1 if not found. + */ +int + lookuparg(Nlist * mac, Token * tp) +{ + Token *ap; + + if (tp->type != NAME || mac->ap == NULL) + return -1; + for (ap = mac->ap->bp; ap < mac->ap->lp; ap++) + { + if (ap->len == tp->len && strncmp((char *) ap->t, (char *) tp->t, ap->len) == 0) + return ap - mac->ap->bp; + } + return -1; +} + +/* + * Return a quoted version of the tokenrow (from # arg) + */ +#define STRLEN 512 +Tokenrow * + stringify(Tokenrow * vp) +{ + static Token t = {STRING, 0, 0, 0, NULL}; + static Tokenrow tr = {&t, &t, &t + 1, 1}; + Token *tp; + uchar s[STRLEN]; + uchar *sp = s, *cp; + int i, instring; + + *sp++ = '"'; + for (tp = vp->bp; tp < vp->lp; tp++) + { + instring = tp->type == STRING || tp->type == CCON; + if (sp + 2 * tp->len >= &s[STRLEN - 10]) + { + error(ERROR, "Stringified macro arg is too long"); + break; + } + for (i = 0, cp = tp->t; (unsigned int)i < tp->len; i++) + { + if (instring && (*cp == '"' || *cp == '\\')) + *sp++ = '\\'; + *sp++ = *cp++; + } + } + *sp++ = '"'; + *sp = '\0'; + sp = s; + t.len = strlen((char *) sp); + t.t = newstring(sp, t.len, 0); + return &tr; +} + +/* + * expand a builtin name + */ +void + builtin(Tokenrow * trp, int biname) +{ + char *op; + Token *tp; + Source *s; + + tp = trp->tp; + trp->tp++; + /* need to find the real source */ + s = cursource; + while (s && s->fd == -1) + s = s->next; + if (s == NULL) + s = cursource; + /* most are strings */ + tp->type = STRING; + if (tp->wslen) + { + *outptr++ = ' '; + tp->wslen = 1; + } + op = outptr; + *op++ = '"'; + switch (biname) + { + + case KLINENO: + tp->type = NUMBER; + op = outnum(op - 1, s->line); + break; + + case KFILE: + { + char *src = s->filename; + + while ((*op++ = *src++) != 0) + if (src[-1] == '\\') + *op++ = '\\'; + op--; + break; + } + + case KDATE: + strncpy(op, curtime + 4, 7); + strncpy(op + 7, curtime + 20, 4); + op += 11; + break; + + case KTIME: + strncpy(op, curtime + 11, 8); + op += 8; + break; + + default: + error(ERROR, "cpp botch: unknown internal macro"); + return; + } + if (tp->type == STRING) + *op++ = '"'; + tp->t = (uchar *) outptr; + tp->len = op - outptr; + outptr = op; +} diff --git a/idlc/source/preproc/makefile.mk b/idlc/source/preproc/makefile.mk new file mode 100644 index 000000000000..e6aa457e8b3d --- /dev/null +++ b/idlc/source/preproc/makefile.mk @@ -0,0 +1,75 @@ +#************************************************************************* +# +# 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=idlc +TARGET=idlcpp +TARGETTYPE=CUI + +# --- Settings ----------------------------------------------------- + +NO_DEFAULT_STL=TRUE +LIBSALCPPRT=$(0) + +.INCLUDE : settings.mk + +# --- Files -------------------------------------------------------- + +OBJFILES= \ + $(OBJ)$/cpp.obj \ + $(OBJ)$/eval.obj \ + $(OBJ)$/include.obj \ + $(OBJ)$/lex.obj \ + $(OBJ)$/macro.obj \ + $(OBJ)$/nlist.obj \ + $(OBJ)$/tokens.obj \ + $(OBJ)$/unix.obj + +# --- CPP ------------------------------------------------------- + +APP1TARGET= $(TARGET) +APP1RPATH=SDK + +.IF "$(GUI)" != "UNX" +.IF "$(COM)" != "GCC" +APP1OBJS=$(OBJ)$/cpp.obj +.ENDIF +.ENDIF + +APP1LIBS= $(LB)$/idlcpp.lib + +.IF "$(HAVE_GETOPT)" != "YES" +.IF "$(GUI)" == "WNT" +APP1STDLIBS=gnu_getopt.lib +.ENDIF +.ENDIF + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + diff --git a/idlc/source/preproc/nlist.c b/idlc/source/preproc/nlist.c new file mode 100644 index 000000000000..f41313c22aac --- /dev/null +++ b/idlc/source/preproc/nlist.c @@ -0,0 +1,143 @@ +/************************************************************************* + * + * 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 <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "cpp.h" + +extern int Cplusplus; +Nlist *kwdefined; +char wd[128]; + +/* + ER: Tabelle extra gross gemacht, da es anscheinend ein Problem mit der + der Verkettung gibt, irgendwann irgendwo wird mal ein nlist->next + ueberschrieben, was in eineme SIGSEGV resultiert. + Den GDB mit watchpoint hab ich aber nach 2 Tagen abgebrochen.. + so loeppt's jedenfalls erstmal.. + */ +#define NLSIZE 15000 + +static Nlist *nlist[NLSIZE]; + +struct kwtab +{ + char *kw; + int val; + int flag; +} kwtab[] = + +{ + { "if", KIF, ISKW }, + { "ifdef", KIFDEF, ISKW }, + { "ifndef", KIFNDEF, ISKW }, + { "elif", KELIF, ISKW }, + { "else", KELSE, ISKW }, + { "endif", KENDIF, ISKW }, + { "include", KINCLUDE, ISKW }, + { "include_next", KINCLUDENEXT, ISKW }, + { "import", KIMPORT, ISKW }, + { "define", KDEFINE, ISKW }, + { "undef", KUNDEF, ISKW }, + { "line", KLINE, ISKW }, + { "error", KERROR, ISKW }, + { "pragma", KPRAGMA, ISKW }, + { "ident", KIDENT, ISKW }, + { "eval", KEVAL, ISKW }, + { "defined", KDEFINED, ISDEFINED + ISUNCHANGE }, + { "machine", KMACHINE, ISDEFINED + ISUNCHANGE }, + { "__LINE__", KLINENO, ISMAC + ISUNCHANGE }, + { "__FILE__", KFILE, ISMAC + ISUNCHANGE }, + { "__DATE__", KDATE, ISMAC + ISUNCHANGE }, + { "__TIME__", KTIME, ISMAC + ISUNCHANGE }, + { "__STDC__", KSTDC, ISUNCHANGE }, + { NULL, 0, 0 } +}; + +unsigned long namebit[077 + 1]; + +void + setup_kwtab(void) +{ + struct kwtab *kp; + Nlist *np; + Token t; + static Token deftoken[1] = {{NAME, 0, 0, 7, (uchar *) "defined"}}; + static Tokenrow deftr = {deftoken, deftoken, deftoken + 1, 1}; + + for (kp = kwtab; kp->kw; kp++) + { + t.t = (uchar *) kp->kw; + t.len = strlen(kp->kw); + np = lookup(&t, 1); + np->flag = (char) kp->flag; + np->val = (char) kp->val; + if (np->val == KDEFINED) + { + kwdefined = np; + np->val = NAME; + np->vp = &deftr; + np->ap = 0; + } + } +} + +Nlist * + lookup(Token * tp, int install) +{ + unsigned int h; + Nlist *np; + uchar *cp, *cpe; + + h = 0; + for (cp = tp->t, cpe = cp + tp->len; cp < cpe;) + h += *cp++; + h %= NLSIZE; + np = nlist[h]; + while (np) + { + if (*tp->t == *np->name && tp->len == (unsigned int)np->len + && strncmp((char *)tp->t, (char *)np->name, tp->len) == 0) + return np; + np = np->next; + } + if (install) + { + np = new(Nlist); + np->vp = NULL; + np->ap = NULL; + np->flag = 0; + np->val = 0; + np->len = tp->len; + np->name = newstring(tp->t, tp->len, 0); + np->next = nlist[h]; + nlist[h] = np; + quickset(tp->t[0], tp->len > 1 ? tp->t[1] : 0); + return np; + } + return NULL; +} diff --git a/idlc/source/preproc/tokens.c b/idlc/source/preproc/tokens.c new file mode 100644 index 000000000000..23ab88a5a9e3 --- /dev/null +++ b/idlc/source/preproc/tokens.c @@ -0,0 +1,534 @@ +/************************************************************************* + * + * 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 <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#if (defined(_WIN32) || defined(_MSDOS) || defined(__IBMC__)) +#include <io.h> +#else +#include <unistd.h> +#endif +#include "cpp.h" + + +static char wbuf[4 * OBS]; +static char *wbp = wbuf; +static int EBCDIC_ExternTokenDetected = 0; +static int EBCDIC_StartTokenDetected = 0; + +unsigned char toLatin1[256] = +{ + 0x00, 0x01, 0x02, 0x03, 0x9c, 0x09, 0x86, 0x7f, 0x97, 0x8d, + 0x8e, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, + 0x9d, 0x0a, 0x08, 0x87, 0x18, 0x19, 0x92, 0x8f, 0x1c, 0x1d, + 0x1e, 0x1f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x17, 0x1b, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07, 0x90, 0x91, + 0x16, 0x93, 0x94, 0x95, 0x96, 0x04, 0x98, 0x99, 0x9a, 0x9b, + 0x14, 0x15, 0x9e, 0x1a, 0x20, 0xa0, 0xe2, 0xe4, 0xe0, 0xe1, + 0xe3, 0xe5, 0xe7, 0xf1, 0xa2, 0x2e, 0x3c, 0x28, 0x2b, 0x7c, + 0x26, 0xe9, 0xea, 0xeb, 0xe8, 0xed, 0xee, 0xef, 0xec, 0xdf, + 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x5e, 0x2d, 0x2f, 0xc2, 0xc4, + 0xc0, 0xc1, 0xc3, 0xc5, 0xc7, 0xd1, 0xa6, 0x2c, 0x25, 0x5f, + 0x3e, 0x3f, 0xf8, 0xc9, 0xca, 0xcb, 0xc8, 0xcd, 0xce, 0xcf, + 0xcc, 0x60, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22, + 0xd8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0xab, 0xbb, 0xf0, 0xfd, 0xfe, 0xb1, 0xb0, 0x6a, 0x6b, 0x6c, + 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0xaa, 0xba, 0xe6, 0xb8, + 0xc6, 0xa4, 0xb5, 0x7e, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7a, 0xa1, 0xbf, 0xd0, 0x5b, 0xde, 0xae, 0xac, 0xa3, + 0xa5, 0xb7, 0xa9, 0xa7, 0xb6, 0xbc, 0xbd, 0xbe, 0xdd, 0xa8, + 0xaf, 0x5d, 0xb4, 0xd7, 0x7b, 0x41, 0x42, 0x43, 0x44, 0x45, + 0x46, 0x47, 0x48, 0x49, 0xad, 0xf4, 0xf6, 0xf2, 0xf3, 0xf5, + 0x7d, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, + 0xb9, 0xfb, 0xfc, 0xf9, 0xfa, 0xff, 0x5c, 0xf7, 0x53, 0x54, + 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0xb2, 0xd4, 0xd6, 0xd2, + 0xd3, 0xd5, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0xb3, 0xdb, 0xdc, 0xd9, 0xda, 0x9f +}; + +#define MASK "\\x%x" + +int + memcpy_EBCDIC( char * pwbuf, uchar *p, int len ) +{ + int currpos = 0; + int processedchars = 0; + + if( len == 0 ) + return 0; + + if( len == 1 ) + { + *pwbuf = *p; + return 1; + } + + /* copy spaces until " or ' */ + while( (p[ processedchars ] != '\"') && (p[ processedchars ] != '\'') ) + pwbuf[ currpos++ ] = p[ processedchars++ ]; + + /* copy first " or ' */ + pwbuf[ currpos++ ] = p[ processedchars++ ]; + + /* convert all characters until " or ' */ + while( processedchars < (len - 1) ) + { + if( p[ processedchars ] == '\\' ) + { + switch( p[ ++processedchars ] ) + { + case 'n': + currpos += sprintf( &pwbuf[ currpos ], MASK, toLatin1['\n'] ); + processedchars++; + break; + + case 't': + currpos += sprintf( &pwbuf[ currpos ], MASK, toLatin1['\t'] ); + processedchars++; + break; + + case 'v': + currpos += sprintf( &pwbuf[ currpos ], MASK, toLatin1['\v'] ); + processedchars++; + break; + + case 'b': + currpos += sprintf( &pwbuf[ currpos ], MASK, toLatin1['\b'] ); + processedchars++; + break; + + case 'r': + currpos += sprintf( &pwbuf[ currpos ], MASK, toLatin1['\r'] ); + processedchars++; + break; + + case 'f': + currpos += sprintf( &pwbuf[ currpos ], MASK, toLatin1['\f'] ); + processedchars++; + break; + + case 'a': + currpos += sprintf( &pwbuf[ currpos ], MASK, toLatin1['\a'] ); + processedchars++; + break; + + case '\\': + currpos += sprintf( &pwbuf[ currpos ], MASK, toLatin1['\\'] ); + processedchars++; + break; + + case '?': + currpos += sprintf( &pwbuf[ currpos ], MASK, toLatin1['\?'] ); + processedchars++; + break; + + case '\'': + currpos += sprintf( &pwbuf[ currpos ], MASK, toLatin1['\''] ); + processedchars++; + break; + + case '"': + currpos += sprintf( &pwbuf[ currpos ], MASK, toLatin1['\"'] ); + processedchars++; + break; + + /* octal coded character? -> copy */ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + { + int startpos = currpos; + + pwbuf[ currpos++ ] = '\\'; + + while( p[ processedchars ] >= '0' && p[ processedchars ] <= '7' && (currpos < startpos + 4) ) + pwbuf[ currpos++ ] = (unsigned char)p[ processedchars++ ]; + break; + } + + /* hex coded character? -> copy */ + case 'x': + case 'X': + { + int startpos = currpos; + + pwbuf[ currpos++ ] = '\\'; + pwbuf[ currpos++ ] = 'x'; + processedchars++; + + while( isxdigit( p[ processedchars ] ) && (currpos < startpos + 4) ) + pwbuf[ currpos++ ] = (unsigned char)p[ processedchars++ ]; + break; + } + + } + } + else + currpos += sprintf( &pwbuf[ currpos ], MASK, toLatin1[p[ processedchars++ ]] ); + + } + + /* copy last " or ' */ + pwbuf[ currpos++ ] = p[ processedchars ]; + + return currpos; +} + +void + maketokenrow(int size, Tokenrow * trp) +{ + trp->max = size; + if (size > 0) + trp->bp = (Token *) domalloc(size * sizeof(Token)); + else + trp->bp = NULL; + trp->tp = trp->bp; + trp->lp = trp->bp; +} + +Token * + growtokenrow(Tokenrow * trp) +{ + int ncur = trp->tp - trp->bp; + int nlast = trp->lp - trp->bp; + + trp->max = 3 * trp->max / 2 + 1; + trp->bp = (Token *) realloc(trp->bp, trp->max * sizeof(Token)); + trp->lp = &trp->bp[nlast]; + trp->tp = &trp->bp[ncur]; + return trp->lp; +} + +/* + * Compare a row of tokens, ignoring the content of WS; return !=0 if different + */ +int + comparetokens(Tokenrow * tr1, Tokenrow * tr2) +{ + Token *tp1, *tp2; + + tp1 = tr1->tp; + tp2 = tr2->tp; + if (tr1->lp - tp1 != tr2->lp - tp2) + return 1; + for (; tp1 < tr1->lp; tp1++, tp2++) + { + if (tp1->type != tp2->type + || (tp1->wslen == 0) != (tp2->wslen == 0) + || tp1->len != tp2->len + || strncmp((char *) tp1->t, (char *) tp2->t, tp1->len) != 0) + return 1; + } + return 0; +} + +/* + * replace ntok tokens starting at dtr->tp with the contents of str. + * tp ends up pointing just beyond the replacement. + * Canonical whitespace is assured on each side. + */ +void + insertrow(Tokenrow * dtr, int ntok, Tokenrow * str) +{ + int nrtok = rowlen(str); + + dtr->tp += ntok; + adjustrow(dtr, nrtok - ntok); + dtr->tp -= ntok; + movetokenrow(dtr, str); + dtr->tp += nrtok; +} + +/* + * make sure there is WS before trp->tp, if tokens might merge in the output + */ +void + makespace(Tokenrow * trp, Token * ntp) +{ + uchar *tt; + Token *tp = trp->tp; + + if (tp >= trp->lp) + return; + + if (ntp->wslen) + { + tt = newstring(tp->t, tp->len, ntp->wslen); + strncpy((char *)tt, (char *)ntp->t - ntp->wslen, ntp->wslen); + tp->t = tt + ntp->wslen; + tp->wslen = ntp->wslen; + tp->flag |= XPWS; + } +} + +/* + * Copy an entire tokenrow into another, at tp. + * It is assumed that there is enough space. + * Not strictly conforming. + */ +void + movetokenrow(Tokenrow * dtr, Tokenrow * str) +{ + int nby; + + /* nby = sizeof(Token) * (str->lp - str->bp); */ + nby = (char *) str->lp - (char *) str->bp; + memmove(dtr->tp, str->bp, nby); +} + +/* + * Move the tokens in a row, starting at tr->tp, rightward by nt tokens; + * nt may be negative (left move). + * The row may need to be grown. + * Non-strictly conforming because of the (char *), but easily fixed + */ +void + adjustrow(Tokenrow * trp, int nt) +{ + int nby, size; + + if (nt == 0) + return; + size = (trp->lp - trp->bp) + nt; + while (size > trp->max) + growtokenrow(trp); + /* nby = sizeof(Token) * (trp->lp - trp->tp); */ + nby = (char *) trp->lp - (char *) trp->tp; + if (nby) + memmove(trp->tp + nt, trp->tp, nby); + trp->lp += nt; +} + +/* + * Copy a row of tokens into the destination holder, allocating + * the space for the contents. Return the destination. + */ +Tokenrow * + copytokenrow(Tokenrow * dtr, Tokenrow * str) +{ + int len = rowlen(str); + + maketokenrow(len, dtr); + movetokenrow(dtr, str); + dtr->lp += len; + return dtr; +} + +/* + * Produce a copy of a row of tokens. Start at trp->tp. + * The value strings are copied as well. The first token + * has WS available. + */ +Tokenrow * + normtokenrow(Tokenrow * trp) +{ + Token *tp; + Tokenrow *ntrp = new(Tokenrow); + int len; + + len = trp->lp - trp->tp; + if (len <= 0) + len = 1; + maketokenrow(len, ntrp); + for (tp = trp->tp; tp < trp->lp; tp++) + { + *ntrp->lp = *tp; + if (tp->len) + { + ntrp->lp->t = newstring(tp->t, tp->len, 1); + *ntrp->lp->t++ = ' '; + if (tp->wslen) + ntrp->lp->wslen = 1; + } + ntrp->lp++; + } + if (ntrp->lp > ntrp->bp) + ntrp->bp->wslen = 0; + return ntrp; +} + +/* + * Debugging + */ +void + peektokens(Tokenrow * trp, char *str) +{ + Token *tp; + + tp = trp->tp; + flushout(); + if (str) + fprintf(stderr, "%s ", str); + if (tp < trp->bp || tp > trp->lp) + fprintf(stderr, "(tp offset %ld) ", (long)(tp - trp->bp)); + for (tp = trp->bp; tp < trp->lp && tp < trp->bp + 32; tp++) + { + if (tp->type != NL) + { + int c = tp->t[tp->len]; + + tp->t[tp->len] = 0; + fprintf(stderr, "%s", tp->t); + tp->t[tp->len] = (uchar) c; + } + fprintf(stderr, tp == trp->tp ? "{%x*} " : "{%x} ", tp->type); + } + fprintf(stderr, "\n"); + fflush(stderr); +} + +void + puttokens(Tokenrow * trp) +{ + Token *tp; + int len; + uchar *p; + + if (Vflag) + peektokens(trp, ""); + tp = trp->bp; + for (; tp < trp->lp; tp++) + { + if (tp->type != NL) + { + len = tp->len + tp->wslen; + p = tp->t - tp->wslen; + + /* EBCDIC to ANSI conversion requested? */ + if( Aflag ) + { + /* keyword __ToLatin1__ found? -> do conversion! */ + if( EBCDIC_StartTokenDetected ) + { + /* previous token was 'extern'? -> don't convert current token! */ + if( EBCDIC_ExternTokenDetected ) + { + EBCDIC_ExternTokenDetected = 0; + memcpy(wbp, p, len); + } + else + { + /* current token is keyword 'extern'? -> don't convert following token! */ + if( (tp->wslen == 0) && (strncmp( (char*)p, "extern", len ) == 0) ) + { + EBCDIC_ExternTokenDetected = 1; + memcpy(wbp, p, len); + } + else + { + /* token is string or char? -> process EBCDIC to ANSI conversion */ + if ((tp->type == STRING) || (tp->type == CCON)) + len = memcpy_EBCDIC(wbp, p, len); + else + memcpy(wbp, p, len); + } + } + } + else + /* keyword __ToLatin1__ found? -> don't copy keyword and start conversion */ + if( (tp->type == NAME) && (strncmp( (char*)p, "__ToLatin1__", len) == 0) ) + { + EBCDIC_StartTokenDetected = 1; + len = 0; + } + else + memcpy(wbp, p, len); + } + else + memcpy(wbp, p, len); + + wbp += len; + } + else + *wbp++ = '\n'; + + if (wbp >= &wbuf[OBS]) + { + if (write(1, wbuf, OBS) != OBS) + error(ERROR, "short write!"); + if (wbp > &wbuf[OBS]) + memcpy(wbuf, wbuf + OBS, wbp - &wbuf[OBS]); + wbp -= OBS; + } + } + trp->tp = tp; + if (cursource->fd == 0) + flushout(); +} + +void + flushout(void) +{ + if (wbp > wbuf) + { + if (write(1, wbuf, wbp - wbuf) != wbp - wbuf) + error(ERROR, "short write!"); + wbp = wbuf; + } +} + +/* + * turn a row into just a newline + */ +void + setempty(Tokenrow * trp) +{ + trp->tp = trp->bp; + trp->lp = trp->bp + 1; + *trp->bp = nltoken; +} + +/* + * generate a number + */ +char * + outnum(char *p, int n) +{ + if (n >= 10) + p = outnum(p, n / 10); + *p++ = (char) (n % 10 + '0'); + return p; +} + +/* + * allocate and initialize a new string from s, of length l, at offset o + * Null terminated. + */ +uchar * + newstring(uchar * s, int l, int o) +{ + uchar *ns = (uchar *) domalloc(l + o + 1); + + ns[l + o] = '\0'; + return (uchar *) strncpy((char *) ns + o, (char *) s, l) - o; +} diff --git a/idlc/source/preproc/unix.c b/idlc/source/preproc/unix.c new file mode 100644 index 000000000000..4997e317e697 --- /dev/null +++ b/idlc/source/preproc/unix.c @@ -0,0 +1,247 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#include <stdio.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <fcntl.h> +#if (defined(_WIN32) || defined(_MSDOS) || defined(__IBMC__)) +#include <io.h> +#include <sys/stat.h> +#include <external/glibc/getopt.h> +#else +#include <unistd.h> +#endif + +#include "cpp.h" + +extern char rcsid[]; + +int Pflag = 0; /* print no line information */ +int Iflag = 0; /* print includes */ +int Mflag = 0; /* print macor expansion */ +int Aflag = 0; /* translate character sets */ +int Xflag = 0; /* print pragma for include/import */ +int Vflag = 0; /* verbose flag */ +int Cflag = 0; /* do not remove any comments */ +int Cplusplus = 0; + +extern void setup_kwtab(void); + +void + setup(int argc, char **argv) +{ + int c, fd, i, n; + char *fp, *dp; + Tokenrow tr; + + setup_kwtab(); + while ((c = getopt(argc, argv, "NOPV:I:D:U:F:A:X:u:l:+")) != -1) + switch (c) + { + case 'N': + for (i = 0; i < NINCLUDE; i++) + if (includelist[i].always == 1) + includelist[i].deleted = 1; + break; + + case 'I': + for (i = NINCLUDE - 2; i >= 0; i--) + { + if (includelist[i].file == NULL) + { + includelist[i].always = 1; + includelist[i].file = optarg; + break; + } + } + if (i < 0) + error(FATAL, "Too many -I directives"); + break; + + case 'D': + case 'U': + case 'A': + setsource("<cmdarg>", -1, -1, optarg, 0); + maketokenrow(3, &tr); + gettokens(&tr, 1); + doadefine(&tr, c); + unsetsource(); + break; + + case 'P': /* Lineinfo */ + Pflag++; + break; + + case 'V': + for (n = 0; (c = optarg[n]) != '\0'; n++) + switch (c) + { + case 'i': + Iflag++; + break; + + case 'm': + Mflag = 1; + break; + + case 'x': + Mflag = 2; + break; + + case 't': + Vflag++; + break; + + case 'v': + fprintf(stderr, "%s %s\n", argv[0], rcsid); + break; + + default: + error(WARNING, "Unknown verbose option %c", c); + } + break; + + case 'X': + for (n = 0; (c = optarg[n]) != '\0'; n++) + switch (c) + { + case 'a': + Aflag++; + break; + + case 'i': + Xflag++; + break; + + case 'c': + Cflag++; + break; + + case 'w': + dp = &optarg[n + 1]; + n += strlen(dp); + while (isspace(*dp)) dp++; + + for (i = NINCLUDE - 1; i >= 0; i--) + { + if (wraplist[i].file == NULL) + { + wraplist[i].file = dp; + break; + } + } + if (i < 0) + error(WARNING, "Too many -Xw directives"); + break; + + default: + error(WARNING, "Unknown extension option %c", c); + } + break; + + case '+': + Cplusplus++; + break; + + case 'u': /* -undef fuer GCC (dummy) */ + case 'l': /* -lang-c++ fuer GCC (dummy) */ + break; + + default: + break; + } + dp = "."; + fp = "<stdin>"; + fd = 0; + if (optind < argc) + { + if ((fp = strrchr(argv[optind], '/')) != NULL) + { + int len = fp - argv[optind]; + + dp = (char *) newstring((uchar *) argv[optind], len + 1, 0); + dp[len] = '\0'; + } + fp = (char *) newstring((uchar *) argv[optind], strlen(argv[optind]), 0); + if ((fd = open(fp, O_RDONLY)) < 0) + error(FATAL, "Can't open input file %s", fp); + } + + if (optind + 1 < argc) + { +#if defined(WNT) && (_MSC_VER >= 1400) + int fdo = creat(argv[optind + 1], _S_IREAD | _S_IWRITE ); +#else + int fdo = creat(argv[optind + 1], 0666 ); +#endif + if (fdo < 0) + error(FATAL, "Can't open output file %s", argv[optind + 1]); + + dup2(fdo, 1); + } + includelist[NINCLUDE - 1].always = 0; + includelist[NINCLUDE - 1].file = dp; + setsource(fp, -1, fd, NULL, 0); +} + + +/* memmove is defined here because some vendors don't provide it at + all and others do a terrible job (like calling malloc) */ + +#if !defined(__IBMC__) && !defined(WNT) && !defined(__GLIBC__) + +void * + memmove(void *dp, const void *sp, size_t n) +{ + unsigned char *cdp, *csp; + + if (n <= 0) + return 0; + cdp = dp; + csp = (unsigned char *) sp; + if (cdp < csp) + { + do + { + *cdp++ = *csp++; + } while (--n); + } + else + { + cdp += n; + csp += n; + do + { + *--cdp = *--csp; + } while (--n); + } + return 0; +} + +#endif diff --git a/idlc/source/scanner.ll b/idlc/source/scanner.ll new file mode 100644 index 000000000000..4125195f5916 --- /dev/null +++ b/idlc/source/scanner.ll @@ -0,0 +1,523 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +%{ +/* + * scanner.ll - Lexical scanner for IDLC 1.0 + */ + +#include <ctype.h> +#include <stdlib.h> +#include <string.h> + +#ifndef _IDLC_IDLC_HXX_ +#include <idlc/idlc.hxx> +#endif +#ifndef _IDLC_ERRORHANDLER_HXX_ +#include <idlc/errorhandler.hxx> +#endif +#ifndef _IDLC_FEHELPER_HXX_ +#include <idlc/fehelper.hxx> +#endif + +#include "attributeexceptions.hxx" + +class AstExpression; +class AstArray; +class AstMember; + +#include <parser.hxx> + +sal_Int32 beginLine = 0; +::rtl::OString docu; + +static int asciiToInteger(char const * s, sal_Int64 * sval, sal_uInt64 * uval) { + bool neg = false; + if (*s == '-') { + neg = true; + ++s; + } + unsigned int base = 10; + if (*s == '0') { + base = 8; + ++s; + if (*s == 'X' || *s == 'x') { + base = 16; + ++s; + } + } + sal_uInt64 val = 0; + for (; *s != 0; ++s) { + unsigned int n; + if (*s >= '0' && *s <= '9') { + n = *s - '0'; + } else { + switch (*s) { + case 'A': + case 'a': + n = 10; + break; + case 'B': + case 'b': + n = 11; + break; + case 'C': + case 'c': + n = 12; + break; + case 'D': + case 'd': + n = 13; + break; + case 'E': + case 'e': + n = 14; + break; + case 'F': + case 'f': + n = 15; + break; + default: + goto done; + } + } + // The following guarantees the invariant val <= SAL_MAX_UINT64 (because + // base and n are sufficiently small), *if* + // std::numeric_limits<sal_uInt64>::max() == SAL_MAX_UINT64: + sal_uInt64 nval = val * base + n; + if (nval < val) { + idlc()->error()->syntaxError( + PS_NoState, idlc()->getLineNumber(), + "integral constant too large"); + val = 0; + break; + } + val = nval; + } + done: + if (neg) { + if (val < SAL_CONST_UINT64(0x8000000000000000)) { + *sval = -static_cast< sal_Int64 >(val); + } else if (val == SAL_CONST_UINT64(0x8000000000000000)) { + *sval = SAL_MIN_INT64; + } else { + idlc()->error()->syntaxError( + PS_NoState, idlc()->getLineNumber(), + "negative integral constant too large"); + *sval = 0; + } + return IDL_INTEGER_LITERAL; + } else if (val <= static_cast< sal_uInt64 >(SAL_MAX_INT64)) { + *sval = static_cast< sal_Int64 >(val); + return IDL_INTEGER_LITERAL; + } else { + *uval = val; + return IDL_INTEGER_ULITERAL; + } +} + +static double asciiToFloat(const sal_Char *s) +{ + double d = 0.0; + double e, k; + sal_Int32 neg = 0, negexp = 0; + + if (*s == '-') + { + neg = 1; + s++; + } + while (*s >= '0' && *s <= '9') + { + d = (d * 10) + *s - '0'; + s++; + } + if (*s == '.') + { + s++; + e = 10; + while (*s >= '0' && *s <= '9') + { + d += (*s - '0') / (e * 1.0); + e *= 10; + s++; + } + } + if (*s == 'e' || *s == 'E') + { + s++; + if (*s == '-') + { + negexp = 1; + s++; + } else + { + if (*s == '+') + s++; + e = 0; + while (*s >= '0' && *s <= '9') + { + e = (e * 10) + *s - '0'; + s++; + } + if (e > 0) + { + for (k = 1; e > 0; k *= 10, e--) ; + if (negexp) + d /= k; + else + d *= k; + } + } + } + if (neg) d *= -1.0; + return d; +} + +static void idlParsePragma(sal_Char* pPragma) +{ + ::rtl::OString pragma(pPragma); + sal_Int32 index = pragma.indexOf("include"); + sal_Char* begin = pPragma + index + 8; + sal_Char* offset = begin; + while (*offset != ',') offset++; + //::rtl::OString include = pragma.copy(index + 8, offset - begin); + idlc()->insertInclude(pragma.copy(index + 8, (sal_Int32)(offset - begin))); +} + +static void parseLineAndFile(sal_Char* pBuf) +{ + sal_Char *r = pBuf; + sal_Char *h; + sal_Bool bIsInMain = sal_False; + + /* Skip initial '#' */ + if (*r != '#') + return; + + /* Find line number */ + for (r++; *r == ' ' || *r == '\t' || isalpha(*r); r++) ; + h = r; + for (; *r != '\0' && *r != ' ' && *r != '\t'; r++) ; + *r++ = 0; + idlc()->setLineNumber((sal_uInt32)atol(h)); + + /* Find file name, if present */ + for (; *r != '"'; r++) + { + if (*r == '\n' || *r == '\0') + return; + } + h = ++r; + for (; *r != '"'; r++) ; + *r = 0; + if (*h == '\0') + idlc()->setFileName(::rtl::OString("standard input")); + else + idlc()->setFileName(::rtl::OString(h)); + + bIsInMain = (idlc()->getFileName() == idlc()->getRealFileName()) ? sal_True : sal_False; + idlc()->setInMainfile(bIsInMain); +} + +// Suppress any warnings from generated code: +#if defined __GNUC__ +#pragma GCC system_header +#elif defined __SUNPRO_CC +#pragma disable_warn +#elif defined _MSC_VER +#pragma warning(push, 1) +/**/ +#ifdef yywrap +#undef yywrap +#define yywrap() 1 +#endif +/**/ +#endif +%} + +%option noyywrap +%option never-interactive + +%x DOCU +%x COMMENT + +DIGIT [0-9] +OCT_DIGIT [0-7] +HEX_DIGIT [a-fA-F0-9] +CAPITAL [A-Z] +ALPHA [a-zA-Z] +INT_LITERAL [1-9][0-9]* +OCT_LITERAL 0{OCT_DIGIT}* +HEX_LITERAL (0x|0X){HEX_DIGIT}* + +IDENTIFIER_NEW ({ALPHA}({ALPHA}|{DIGIT})*)|({CAPITAL}("_"?({ALPHA}|{DIGIT})+)*) +IDENTIFIER ("_"?({ALPHA}|{DIGIT})+)* + +%% + +[ \t\r]+ ; /* eat up whitespace */ +[\n] { + idlc()->incLineNumber(); +} + +attribute return IDL_ATTRIBUTE; +bound return IDL_BOUND; +case return IDL_CASE; +const return IDL_CONST; +constants return IDL_CONSTANTS; +constrained return IDL_CONSTRAINED; +default return IDL_DEFAULT; +enum return IDL_ENUM; +exception return IDL_EXCEPTION; +interface return IDL_INTERFACE; +maybeambiguous return IDL_MAYBEAMBIGUOUS; +maybedefault return IDL_MAYBEDEFAULT; +maybevoid return IDL_MAYBEVOID; +module return IDL_MODULE; +needs return IDL_NEEDS; +observes return IDL_OBSERVES; +optional return IDL_OPTIONAL; +property return IDL_PROPERTY; +raises return IDL_RAISES; +readonly return IDL_READONLY; +removable return IDL_REMOVEABLE; +service return IDL_SERVICE; +sequence return IDL_SEQUENCE; +singleton return IDL_SINGLETON; +struct return IDL_STRUCT; +switch return IDL_SWITCH; +transient return IDL_TRANSIENT; +typedef return IDL_TYPEDEF; +union return IDL_UNION; + +any return IDL_ANY; +boolean return IDL_BOOLEAN; +byte return IDL_BYTE; +char return IDL_CHAR; +double return IDL_DOUBLE; +float return IDL_FLOAT; +hyper return IDL_HYPER; +long return IDL_LONG; +short return IDL_SHORT; +string return IDL_STRING; +type return IDL_TYPE; +unsigned return IDL_UNSIGNED; +void return IDL_VOID; + +TRUE return IDL_TRUE; +True return IDL_TRUE; +FALSE return IDL_FALSE; +False return IDL_FALSE; + +in return IDL_IN; +out return IDL_OUT; +inout return IDL_INOUT; +oneway return IDL_ONEWAY; + +get return IDL_GET; +set return IDL_SET; + +published return IDL_PUBLISHED; + +"..." return IDL_ELLIPSIS; + +("-")?{INT_LITERAL}+(l|L|u|U)? { + return asciiToInteger(yytext, &yylval.ival, &yylval.uval); + } + +("-")?{OCT_LITERAL}+(l|L|u|U)? { + return asciiToInteger(yytext, &yylval.ival, &yylval.uval); + } + +("-")?{HEX_LITERAL}+(l|L|u|U)? { + return asciiToInteger(yytext, &yylval.ival, &yylval.uval); + } + +("-")?{DIGIT}+(e|E){1}(("+"|"-")?{DIGIT}+)+(f|F)? | +("-")?"."{DIGIT}+((e|E)("+"|"-")?{DIGIT}+)?(f|F)? | +("-")?{DIGIT}*"."{DIGIT}+((e|E)("+"|"-")?{DIGIT}+)?(f|F)? { + yylval.dval = asciiToFloat( yytext ); + return IDL_FLOATING_PT_LITERAL; + } + +{IDENTIFIER} { + yylval.sval = new ::rtl::OString(yytext); + return IDL_IDENTIFIER; + } + +\<\< { + yylval.strval = yytext; + return IDL_LEFTSHIFT; + } +\>\> { + yylval.strval = yytext; + return IDL_RIGHTSHIFT; + } +\:\: { + yylval.strval = yytext; + return IDL_SCOPESEPARATOR; + } + +"/*" { + BEGIN( COMMENT ); + docu = ::rtl::OString(); + beginLine = idlc()->getLineNumber(); + } + +"/***" { + BEGIN( COMMENT ); + docu = ::rtl::OString(); + beginLine = idlc()->getLineNumber(); + } + +<COMMENT>[^*]+ { + docu += ::rtl::OString(yytext); + } + +<COMMENT>"*"[^*/]+ { + docu += ::rtl::OString(yytext); + } + +<COMMENT>"**" { + docu += ::rtl::OString(yytext); + } + +<COMMENT>[*]+"/" { + docu = docu.trim(); + sal_Int32 nIndex = 0; + int count = 0; + do { docu.getToken( 0, '\n', nIndex ); count++; } while( nIndex != -1 ); + idlc()->setLineNumber( beginLine + count - 1); + BEGIN( INITIAL ); + } + +"/**" { + BEGIN( DOCU ); + docu = ::rtl::OString(); + beginLine = idlc()->getLineNumber(); + } + +<DOCU>[^*\n]+ { + docu += ::rtl::OString(yytext); + } + +<DOCU>"\n"[ \t]*"*"{1} { + idlc()->setLineNumber( idlc()->getLineNumber() + 1); + docu += ::rtl::OString("\n"); + } + +<DOCU>"\n" { + idlc()->setLineNumber( idlc()->getLineNumber() + 1); + docu += ::rtl::OString(yytext); + } + +<DOCU>"*"[^*^/\n]* { + docu += ::rtl::OString(yytext); + } + +<DOCU>"\n"[ \t]*"*/" { + docu = docu.trim(); + sal_Int32 nIndex = 0; + int count = 0; + do { docu.getToken( 0, '\n', nIndex ); count++; } while( nIndex != -1 ); + idlc()->setLineNumber( beginLine + count - 1); + if ( (nIndex = docu.indexOf("/*")) >= 0 || (nIndex = docu.indexOf("///")) >= 0 ) + { + if ( 0 != nIndex && + (docu.getStr()[nIndex - 1] != '"' && docu.getStr()[nIndex - 1] != ':') ) + idlc()->error()->syntaxError(PS_NoState, idlc()->getLineNumber(), + "nested documentation strings are not allowed!"); + } + idlc()->setDocumentation(docu); + BEGIN( INITIAL ); + } + +<DOCU>"*/" { + docu = docu.trim(); + sal_Int32 nIndex = 0; + int count = 0; + do { docu.getToken( 0, '\n', nIndex ); count++; } while( nIndex != -1 ); + idlc()->setLineNumber( beginLine + count - 1); + if ( docu.indexOf("/*") >= 0 || docu.indexOf("//") >= 0 ) + { + if ( 0 != nIndex && + (docu.getStr()[nIndex - 1] != '"' && docu.getStr()[nIndex - 1] != ':') ) + idlc()->error()->syntaxError(PS_NoState, idlc()->getLineNumber(), + "nested documentation strings are not allowed!"); + } + idlc()->setDocumentation(docu); + BEGIN( INITIAL ); + } + +"//"[^/]{1}.*"\n" { + /* only a comment */ + ::rtl::OString docStr(yytext); + docStr = docStr.copy( 0, docStr.lastIndexOf('\n') ); + docStr = docStr.copy( docStr.lastIndexOf('/')+1 ); + docStr = docStr.trim(); + idlc()->incLineNumber(); + } + +"///".*"\n" { + ::rtl::OString docStr(yytext); + docStr = docStr.copy( 0, docStr.lastIndexOf('\n') ); + docStr = docStr.copy( docStr.lastIndexOf('/')+1 ); + docStr = docStr.trim(); + idlc()->incLineNumber(); + idlc()->setDocumentation(docStr); + } + +. return yytext[0]; + +^#[ \t]*line[ \t]*[0-9]*" ""\""[^\"]*"\""\n { + parseLineAndFile(yytext); +} + +^#[ \t]*[0-9]*" ""\""[^\"]*"\""" "[0-9]*\n { + parseLineAndFile(yytext); +} + +^#[ \t]*[0-9]*" ""\""[^\"]*"\""\n { + parseLineAndFile(yytext); +} + +^#[ \t]*[0-9]*\n { + parseLineAndFile(yytext); +} + +^#[ \t]*ident.*\n { + /* ignore cpp ident */ + idlc()->incLineNumber(); +} + +^#[ \t]*pragma[ \t].*\n { /* remember pragma */ + idlParsePragma(yytext); + idlc()->incLineNumber(); +} + +%% diff --git a/idlc/source/wrap_parser.cxx b/idlc/source/wrap_parser.cxx new file mode 100644 index 000000000000..5b9abfbf417a --- /dev/null +++ b/idlc/source/wrap_parser.cxx @@ -0,0 +1,31 @@ +/************************************************************************* + * + * 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_idlc.hxx" + +#include "parser.cxx" diff --git a/idlc/source/wrap_scanner.cxx b/idlc/source/wrap_scanner.cxx new file mode 100644 index 000000000000..f87bc4591c7b --- /dev/null +++ b/idlc/source/wrap_scanner.cxx @@ -0,0 +1,31 @@ +/************************************************************************* + * + * 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_idlc.hxx" + +#include "scanner.cxx" diff --git a/idlc/test/const.idl b/idlc/test/const.idl new file mode 100644 index 000000000000..76b3d2a02e6b --- /dev/null +++ b/idlc/test/const.idl @@ -0,0 +1,50 @@ +module idlc +{ +module test +{ + const long l = 1; + const long add = 1 + 2; + const long sub = 3 - 2; + const hyper h = 123456789; + const float f7 = 3.4123; + const float f2 = 3.4123 + 10e-12; + const boolean bt = True; + const boolean bf = False; + const boolean and = bt & bf; + + /// SHORT_MAX + 1; + const short shortMax = -0x8000; + /// LONG_MAX + 1; + const unsigned long longMax = 0x80000000; + + +constants USER +{ + /// = 1 + const long FLAG1 = 0x00000001; + /// = 2 + const long FLAG2 = 0x00000002; + /// = 4 + const long FLAG3 = 0x00000004; + /// = 8 + const long FLAG4 = 0x00000008; + /// = 16 + const long FLAG5 = 0x00000010; + /// = 0 + const long FLAG6 = FLAG1 & FLAG2; + /// = 3 + const long FLAG7 = FLAG1 | FLAG2; + /// = 2 + const long FLAG8 = (FLAG1 | FLAG2) & FLAG2; + /// = 4 + const long FLAG9 = FLAG1 << 2; + /// = 32 + const long FLAG10 = (FLAG5 >> 1) << 2; + /// = 1 + const long FLAG11 = 33 % 4; + /// = 4 + const long FLAG12 = FLAG10 / 8; +}; + +}; +}; diff --git a/idlc/test/enum.idl b/idlc/test/enum.idl new file mode 100644 index 000000000000..2920d7fe6a0f --- /dev/null +++ b/idlc/test/enum.idl @@ -0,0 +1,24 @@ +module idlc +{ +module test +{ + +enum Error +{ + NONE, + FATAL, + SYSTEM, + RUNTIME +}; + +enum Warning +{ + NO, + USER = 2, + WRONGPASSWORD = 4, + IDFAILURE +}; + + +}; +}; diff --git a/idlc/test/exception.idl b/idlc/test/exception.idl new file mode 100644 index 000000000000..b53d1dbe74fd --- /dev/null +++ b/idlc/test/exception.idl @@ -0,0 +1,20 @@ +module idlc +{ +module test +{ + +exception BaseException +{ + string Description; +}; + +exception RuntimeException : BaseException +{ + long Id; + type Context; +}; + + +}; +}; + diff --git a/idlc/test/identifiers.idl b/idlc/test/identifiers.idl new file mode 100644 index 000000000000..d7af48867cf3 --- /dev/null +++ b/idlc/test/identifiers.idl @@ -0,0 +1,22 @@ +struct Identifiers +{ + long onlysmallalphas; + long smallMixedAlphas; + long CapMixedAlphas; + long ONLYCAPS; + long CAPS_WITH_UNDERSCORE; + long CAPS_WITH_UNDERSCORE_11; + long CAPS_WITH_UNDERSCORE11_11TEST; + long CapMixed_Alphas_11; + long m_CapMixedAlphas_11; // should be not allowed with -cid + long small_get; //should be not allowed with -cid + long small_11; //should be not allowed with -cid + long small_11small; //should be not allowed with -cid + long mixedAlphas_11CAPS; // should be not allowed with -cid + long mixedAlphas_11mixedAlphas; // should be not allowed with -cid + long _mixedAlphas; // should be not allowed with -cid +// long _mixedAlphas_; // should be not allowed +// long CapsMixedAlphas_; // should be not allowed +// long _CapsMixedAlphas_; // should be not allowed + +}; diff --git a/idlc/test/interface.idl b/idlc/test/interface.idl new file mode 100644 index 000000000000..18116bf963db --- /dev/null +++ b/idlc/test/interface.idl @@ -0,0 +1,51 @@ +#include <enum.idl> +#include <struct.idl> + +module idlc +{ + +module test +{ + +interface XBase +{ + [readonly, attribute] string description; + + string getDescription(); +}; + +interface XTestBaseTypes : XBase +{ + void voidFunc(); + [oneway] void onewayFunc(); + + short shortFunc( [in] short inparam, [out] short outparam, [inout] short inoutparam); + unsigned short uShortFunc( [in] unsigned short inparam, [out] unsigned short outparam, [inout] unsigned short inoutparam); + + long longFunc( [in] long inparam, [out] long outparam, [inout] long inoutparam); + unsigned long ulongFunc( [in] unsigned long inparam, [out] unsigned long outparam, [inout] unsigned long inoutparam); + + hyper hyperFunc( [in] hyper inparam, [out] hyper outparam, [inout] hyper inoutparam); + unsigned hyper uHyperFunc( [in] unsigned hyper inparam, [out] unsigned hyper outparam, [inout] unsigned hyper inoutparam); + + float floatFunc( [in] float inparam, [out] float outparam, [inout] float inoutparam); + double doubleFunc( [in] double inparam, [out] double outparam, [inout] double inoutparam); + char charFunc( [in] char inparam, [out] char outparam, [inout] char inoutparam); + string stringFunc( [in] string inparam, [out] string outparam, [inout] string inoutparam); + byte byteFunc( [in] byte inparam, [out] byte outparam, [inout] byte inoutparam); + + type typeFunc( [in] type inparam, [out] type outparam, [inout] type inoutparam); + any anyFunc( [in] any inparam, [out] any outparam, [inout] any inoutparam); +}; + + +interface XTestComplexTypes : XBase +{ + Error enumFunc( [in] Error inparam, [out] Error outparam, [inout] Error inoutparam); + + BaseStruct structFunc( [in] ::idlc::test::BaseStruct inparam, [out] idlc::test::BaseStruct outparam, [inout] BaseStruct inoutparam); +}; + +}; + +}; diff --git a/idlc/test/parser/attribute.tests b/idlc/test/parser/attribute.tests new file mode 100644 index 000000000000..2d12bd85bbb7 --- /dev/null +++ b/idlc/test/parser/attribute.tests @@ -0,0 +1,223 @@ +#************************************************************************* +# +# 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. +# +#************************************************************************* + +EXPECT SUCCESS "attribute.tests 1": +interface I1 { + [attribute] long a; +}; + + +EXPECT SUCCESS "attribute.tests 2": +interface I1 { + [attribute] long a {}; +}; + + +EXPECT FAILURE "attribute.tests 3": +interface I1 { + [attribute] long a { + get raises (); + }; +}; + + +EXPECT SUCCESS "attribute.tests 4": +exception E1 {}; +interface I1 { + [attribute] long a { + get raises (E1); + }; +}; + + +EXPECT SUCCESS "attribute.tests 5": +exception E1 {}; +interface I1 { + [attribute] long a { + set raises (E1); + }; +}; + + +EXPECT SUCCESS "attribute.tests 6": +exception E1 {}; +interface I1 { + [attribute] long a { + get raises (E1); + set raises (E1); + }; +}; + + +EXPECT SUCCESS "attribute.tests 7": +exception E1 {}; +interface I1 { + [attribute] long a { + set raises (E1); + get raises (E1); + }; +}; + + +EXPECT FAILURE "attribute.tests 8": +exception E1 {}; +interface I1 { + [attribute] long a { + get raises (E1); + get raises (E1); + }; +}; + + +EXPECT FAILURE "attribute.tests 9": +exception E1 {}; +interface I1 { + void E1(); + [attribute] long a { + get raises (E1); + }; +}; + + +EXPECT FAILURE "attribute.tests 10": +exception E1 {}; +interface I1 { + [attribute] long E1 { + get raises (E1); + }; +}; + + +EXPECT SUCCESS "attribute.tests 11": +exception E1 {}; +interface I1 { + [attribute] long a { + get raises (E1,E1); + }; +}; + + +EXPECT SUCCESS "attribute.tests 12": +exception E1 {}; +interface I1 { + [attribute, readonly] long a { + get raises (E1); + }; +}; + + +EXPECT FAILURE "attribute.tests 13": +exception E1 {}; +interface I1 { + [attribute, readonly] long a { + set raises (E1); + }; +}; + + +EXPECT FAILURE "attribute.tests 14": +interface I1 { + [] long a; +}; + + +EXPECT SUCCESS "attribute.tests 15": +interface I1 { + [attribute] long a; +}; + + +EXPECT FAILURE "attribute.tests 16": +interface I1 { + [attribute, property] long a; +}; + + +EXPECT FAILURE "attribute.tests 17": +interface I1 { + [attribute, optional] long a; +}; + + +EXPECT FAILURE "attribute.tests 18": +interface I1 { + [attribute, maybevoid] long a; +}; + + +EXPECT FAILURE "attribute.tests 19": +interface I1 { + [attribute, constrained] long a; +}; + + +EXPECT FAILURE "attribute.tests 20": +interface I1 { + [attribute, transient] long a; +}; + + +EXPECT FAILURE "attribute.tests 21": +interface I1 { + [attribute, maybeambigious] long a; +}; + + +EXPECT FAILURE "attribute.tests 22": +interface I1 { + [attribute, maybedefault] long a; +}; + + +EXPECT FAILURE "attribute.tests 23": +interface I1 { + [attribute, removeable] long a; +}; + + +EXPECT SUCCESS "attribute.tests 24": +interface I1 { + [attribute, bound] long a; +}; + + +EXPECT SUCCESS "attribute.tests 25": +interface I1 { + [bound, attribute] long a; +}; + + +EXPECT SUCCESS "attribute.tests 26": +interface I1 { + [attribute, readonly] long a; +}; + + +EXPECT SUCCESS "attribute.tests 27": +interface I1 { + [attribute, bound, readonly] long a; +}; diff --git a/idlc/test/parser/constant.tests b/idlc/test/parser/constant.tests new file mode 100644 index 000000000000..2a0d19b03090 --- /dev/null +++ b/idlc/test/parser/constant.tests @@ -0,0 +1,295 @@ +#************************************************************************* +# +# 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. +# +#************************************************************************* + +EXPECT SUCCESS "constant.tests 1": +constants C { + const boolean C1 = FALSE; + const byte C2 = 0; + const short C3 = 0; + const unsigned short C4 = 0; + const long C5 = 0; + const unsigned long C6 = 0; + const hyper C7 = 0; + const unsigned hyper C8 = 0; + const float C9 = 0.0; + const double C10 = 0.0; +}; + + +EXPECT SUCCESS "constant.tests 2": +module m { + const boolean C1 = FALSE; + const byte C2 = 0; + const short C3 = 0; + const unsigned short C4 = 0; + const long C5 = 0; + const unsigned long C6 = 0; + const hyper C7 = 0; + const unsigned hyper C8 = 0; + const float C9 = 0.0; + const double C10 = 0.0; +}; + + +EXPECT FAILURE "constant.tests 3": +constants C { + const char C1 = 'A'; +}; + + +EXPECT FAILURE "constant.tests 4": +module m { + const char C1 = 'A'; +}; + + +EXPECT FAILURE "constant.tests 5": +constants C { + const string C1 = ""; +}; + + +EXPECT FAILURE "constant.tests 6": +module m { + const string C1 = ""; +}; + + +EXPECT SUCCESS "constant.tests 7": +constants C {}; + + +EXPECT SUCCESS "constant.tests 8": +module m { + const byte C1 = -128; + const byte C2 = -0200; + const byte C3 = -0x80; + const byte C4 = 255; + const byte C5 = 0377; + const byte C6 = 0xFF; + const short C7 = -32768; + const short C8 = -0100000; + const short C9 = -0x8000; + const short C10 = 32767; + const short C11 = 077777; + const short C12 = 0x7FFF; + const unsigned short C13 = 0; + const unsigned short C14 = 0x0; + const unsigned short C15 = 65535; + const unsigned short C16 = 0177777; + const unsigned short C17 = 0xFFFF; + const long C18 = -2147483648; + const long C19 = -020000000000; + const long C20 = -0x80000000; + const long C21 = 2147483647; + const long C22 = 017777777777; + const long C23 = 0x7FFFFFFF; + const unsigned long C24 = 0; + const unsigned long C25 = 0x0; + const unsigned long C26 = 4294967295; + const unsigned long C27 = 037777777777; + const unsigned long C28 = 0xFFFFFFFF; + const hyper C29 = -9223372036854775808; + const hyper C30 = -01000000000000000000000; + const hyper C31 = -0x8000000000000000; + const hyper C32 = 9223372036854775807; + const hyper C33 = 0777777777777777777777; + const hyper C34 = 0x7FFFFFFFFFFFFFFF; + const unsigned hyper C35 = 0; + const unsigned hyper C36 = 0x0; + const unsigned hyper C37 = 18446744073709551615; + const unsigned hyper C38 = 01777777777777777777777; + const unsigned hyper C39 = 0xFFFFFFFFFFFFFFFF; +}; + + +EXPECT FAILURE "constant.tests 9": +module m { const byte C = -129; }; + + +EXPECT FAILURE "constant.tests 10": +module m { const byte C = -0201; }; + + +EXPECT FAILURE "constant.tests 11": +module m { const byte C = -0x81; }; + + +EXPECT FAILURE "constant.tests 12": +module m { const byte C = 256; }; + + +EXPECT FAILURE "constant.tests 13": +module m { const byte C = 0400; }; + + +EXPECT FAILURE "constant.tests 14": +module m { const byte C = 0x100; }; + + +EXPECT FAILURE "constant.tests 15": +module m { const short C = -32769; }; + + +EXPECT FAILURE "constant.tests 16": +module m { const short C = -0100001; }; + + +EXPECT FAILURE "constant.tests 17": +module m { const short C = -0x8001; }; + + +EXPECT FAILURE "constant.tests 18": +module m { const short C = 32768; }; + + +EXPECT FAILURE "constant.tests 19": +module m { const short C = 0100000; }; + + +EXPECT FAILURE "constant.tests 20": +module m { const short C = 0x8000; }; + + +EXPECT FAILURE "constant.tests 21": +module m { const unsigned short C = -1; }; + + +EXPECT FAILURE "constant.tests 22": +module m { const unsigned short C = -01; }; + + +EXPECT FAILURE "constant.tests 23": +module m { const unsigned short C = -0x1; }; + + +EXPECT FAILURE "constant.tests 24": +module m { const unsigned short C = 65536; }; + + +EXPECT FAILURE "constant.tests 25": +module m { const unsigned short C = 0200000; }; + + +EXPECT FAILURE "constant.tests 26": +module m { const unsigned short C = 0x10000; }; + + +EXPECT FAILURE "constant.tests 27": +module m { const long C = -2147483649; }; + + +EXPECT FAILURE "constant.tests 28": +module m { const long C = -020000000001; }; + + +EXPECT FAILURE "constant.tests 29": +module m { const long C = -0x80000001; }; + + +EXPECT FAILURE "constant.tests 30": +module m { const long C = 2147483648; }; + + +EXPECT FAILURE "constant.tests 31": +module m { const long C = 020000000000; }; + + +EXPECT FAILURE "constant.tests 32": +module m { const long C = 0x80000000; }; + + +EXPECT FAILURE "constant.tests 33": +module m { const unsigned long C = -1; }; + + +EXPECT FAILURE "constant.tests 34": +module m { const unsigned long C = -01; }; + + +EXPECT FAILURE "constant.tests 35": +module m { const unsigned long C = -0x1; }; + + +EXPECT FAILURE "constant.tests 36": +module m { const unsigned long C = 4294967296; }; + + +EXPECT FAILURE "constant.tests 37": +module m { const unsigned long C = 040000000000; }; + + +EXPECT FAILURE "constant.tests 38": +module m { const unsigned long C = 0x100000000; }; + + +EXPECT FAILURE "constant.tests 39": +module m { const hyper C = -9223372036854775809; }; + + +EXPECT FAILURE "constant.tests 40": +module m { const hyper C = -01000000000000000000001; }; + + +EXPECT FAILURE "constant.tests 41": +module m { const hyper C = -0x8000000000000001; }; + + +EXPECT FAILURE "constant.tests 42": +module m { const hyper C = 9223372036854775808; }; + + +EXPECT FAILURE "constant.tests 43": +module m { const hyper C = 01000000000000000000000; }; + + +EXPECT FAILURE "constant.tests 44": +module m { const hyper C = 0x8000000000000000; }; + + +EXPECT FAILURE "constant.tests 45": +module m { const unsigned hyper C = -1; }; + + +EXPECT FAILURE "constant.tests 46": +module m { const unsigned hyper C = -01; }; + + +EXPECT FAILURE "constant.tests 47": +module m { const unsigned hyper C = -0x1; }; + + +EXPECT FAILURE "constant.tests 48": +module m { const unsigned hyper C = 18446744073709551616; }; + + +EXPECT FAILURE "constant.tests 49": +module m { const unsigned hyper C = 02000000000000000000000; }; + + +EXPECT FAILURE "constant.tests 50": +module m { const unsigned hyper C = 0x10000000000000000; }; diff --git a/idlc/test/parser/constructor.tests b/idlc/test/parser/constructor.tests new file mode 100644 index 000000000000..7270fe99aabb --- /dev/null +++ b/idlc/test/parser/constructor.tests @@ -0,0 +1,199 @@ +#************************************************************************* +# +# 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. +# +#************************************************************************* + +EXPECT SUCCESS "constructor.tests 1": +interface X {}; +service S: X; + + +EXPECT SUCCESS "constructor.tests 2": +interface X {}; +service S: X {}; + + +EXPECT SUCCESS "constructor.tests 3": +interface X {}; +service S: X { + f(); +}; + + +EXPECT FAILURE "constructor.tests 4": +interface X {}; +service S: X { + f(); + f(); +}; + + +EXPECT FAILURE "constructor.tests 5": +interface X { + void f([in] any... p); +}; + + +EXPECT FAILURE "constructor.tests 6": +interface X { + void f([out] any... p); +}; + + +EXPECT SUCCESS "constructor.tests 7": +interface X {}; +service S: X { + f([in] any... p); +}; + + +EXPECT SUCCESS "constructor.tests 8": +interface X {}; +typedef any some; +service S: X { + f([in] some... p); +}; + + +EXPECT FAILURE "constructor.tests 9": +interface X {}; +service S: X { + f([in] long p1, [in] any... p2); +}; + + +EXPECT FAILURE "constructor.tests 10": +interface X {}; +service S: X { + f([in] any... p2, [in] long p1); +}; + + +EXPECT FAILURE "constructor.tests 11": +interface X {}; +service S: X { + f([in] long p1, [in] long... p2); +}; + + +EXPECT FAILURE "constructor.tests 12": +interface X {}; +service S: X { + f([out] long p); +}; + + +EXPECT FAILURE "constructor.tests 13": +interface X {}; +service S: X { + f([out] any... p); +}; + + +EXPECT FAILURE "constructor.tests 14": +interface X {}; +singleton S: X { + f(); +}; + + +EXPECT FAILURE "constructor.tests 15": +module com { module sun { module star { module test { + interface X {}; +service S: com::sun::star::test::X { + c1([in] long a, [in] com::sun::star::test::X b); + c2([in] long c, [in] X d); +}; +}; }; }; }; + + +EXPECT FAILURE "constructor.tests 16": +module com { module sun { module star { module test { + interface X {}; +}; }; }; }; +typedef long T; +service S: com::sun::star::test::X { + c1([in] sequence<long> a); + c2([in] sequence<T> b); +}; + + +EXPECT FAILURE "constructor.tests 17": +module com { module sun { module star { module test { + interface X {}; +}; }; }; }; +service S: com::sun::star::test::X { + c1([in] any... a); + c2([in] any... b); +}; + + +EXPECT SUCCESS "constructor.tests 18": +module com { module sun { module star { module test { + interface X {}; +}; }; }; }; +service S: com::sun::star::test::X { + c1([in] any... a); + c2([in] sequence<any> b); +}; + + +EXPECT SUCCESS "constructor.tests 19": +module com { module sun { module star { module test { + interface X { void m(); }; +}; }; }; }; +service S: com::sun::star::test::X { + c([in] any... a); +}; + + +EXPECT SUCCESS "constructor.tests 20": +module com { module sun { module star { module uno { + interface XInterface { void m(); }; +}; }; }; }; +service S: com::sun::star::uno::XInterface { + c1([in] long a, [in] long b); + c2([in] long a); +}; + + +EXPECT SUCCESS "constructor.tests 21": +module com { module sun { module star { module uno { + interface XInterface { void m(); }; +}; }; }; }; +service S: com::sun::star::uno::XInterface { + c1([in] long a); + c2([in] long a, [in] long b); +}; + + +EXPECT SUCCESS "constructor.tests 22": +module com { module sun { module star { module uno { + interface XInterface { void m(); }; +}; }; }; }; +service S: com::sun::star::uno::XInterface { + c1([in] long a, [in] short b); + c2([in] long a, [in] long b); +}; diff --git a/idlc/test/parser/interfaceinheritance.tests b/idlc/test/parser/interfaceinheritance.tests new file mode 100644 index 000000000000..85fd7f1de07c --- /dev/null +++ b/idlc/test/parser/interfaceinheritance.tests @@ -0,0 +1,280 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +EXPECT FAILURE "interfaceinheritance.tests 1": +interface Base {}; +interface Derived { + interface Base; + interface Base; +}; + + +EXPECT FAILURE "interfaceinheritance.tests 2": +interface Base {}; +interface Derived { + interface Base; + [optional] interface Base; +}; + + +EXPECT FAILURE "interfaceinheritance.tests 3": +interface Base {}; +interface Derived { + [optional] interface Base; + interface Base; +}; + + +EXPECT FAILURE "interfaceinheritance.tests 4": +interface Base {}; +interface Derived { + [optional] interface Base; + [optional] interface Base; +}; + + +EXPECT FAILURE "interfaceinheritance.tests 5": +interface Base1 {}; +interface Base2: Base1 {}; +interface Derived { + interface Base1; + interface Base2; +}; + + +EXPECT FAILURE "interfaceinheritance.tests 6": +interface Base1 {}; +interface Base2: Base1 {}; +interface Derived { + interface Base2; + interface Base1; +}; + + +EXPECT FAILURE "interfaceinheritance.tests 7": +interface Base1 {}; +interface Base2: Base1 {}; +interface Derived { + [optional] interface Base1; + interface Base2; +}; + + +EXPECT FAILURE "interfaceinheritance.tests 8": +interface Base1 {}; +interface Base2: Base1 {}; +interface Derived { + interface Base2; + [optional] interface Base1; +}; + + +EXPECT SUCCESS "interfaceinheritance.tests 9": +interface Base1 {}; +interface Base2: Base1 {}; +interface Derived { + interface Base1; + [optional] interface Base2; +}; + + +EXPECT SUCCESS "interfaceinheritance.tests 10": +interface Base1 {}; +interface Base2: Base1 {}; +interface Derived { + [optional] interface Base2; + interface Base1; +}; + + +EXPECT SUCCESS "interfaceinheritance.tests 11": +interface Base1 {}; +interface Base2: Base1 {}; +interface Derived { + [optional] interface Base1; + [optional] interface Base2; +}; + + +EXPECT SUCCESS "interfaceinheritance.tests 12": +interface Base1 {}; +interface Base2: Base1 {}; +interface Derived { + [optional] interface Base2; + [optional] interface Base1; +}; + + +EXPECT SUCCESS "interfaceinheritance.tests 13": +interface Base1 {}; +interface Base2 { [optional] interface Base1; }; +interface Derived { + interface Base1; + interface Base2; +}; + + +EXPECT SUCCESS "interfaceinheritance.tests 14": +interface Base1 {}; +interface Base2 { [optional] interface Base1; }; +interface Derived { + interface Base2; + interface Base1; +}; + + +EXPECT FAILURE "interfaceinheritance.tests 15": +interface Base1 {}; +interface Base2 { [optional] interface Base1; }; +interface Derived { + [optional] interface Base1; + interface Base2; +}; + + +EXPECT FAILURE "interfaceinheritance.tests 16": +interface Base1 {}; +interface Base2 { [optional] interface Base1; }; +interface Derived { + interface Base2; + [optional] interface Base1; +}; + + +EXPECT SUCCESS "interfaceinheritance.tests 17": +interface Base1 {}; +interface Base2 { [optional] interface Base1; }; +interface Derived { + interface Base1; + [optional] interface Base2; +}; + + +EXPECT SUCCESS "interfaceinheritance.tests 18": +interface Base1 {}; +interface Base2 { [optional] interface Base1; }; +interface Derived { + [optional] interface Base2; + interface Base1; +}; + + +EXPECT SUCCESS "interfaceinheritance.tests 19": +interface Base1 {}; +interface Base2 { [optional] interface Base1; }; +interface Derived { + [optional] interface Base1; + [optional] interface Base2; +}; + + +EXPECT SUCCESS "interfaceinheritance.tests 20": +interface Base1 {}; +interface Base2 { [optional] interface Base1; }; +interface Derived { + [optional] interface Base2; + [optional] interface Base1; +}; + + +EXPECT SUCCESS "interfaceinheritance.tests 21": +interface Base1 {}; +interface Base2: Base1 {}; +interface Base3: Base1 {}; +interface Derived { + interface Base2; + interface Base3; +}; + + +EXPECT SUCCESS "interfaceinheritance.tests 22": +interface Base1 {}; +interface Base2: Base1 {}; +interface Base3: Base1 {}; +interface Derived { + [optional] interface Base2; + interface Base3; +}; + + +EXPECT SUCCESS "interfaceinheritance.tests 23": +interface Base1 {}; +interface Base2: Base1 {}; +interface Base3: Base1 {}; +interface Derived { + interface Base2; + [optional] interface Base3; +}; + + +EXPECT SUCCESS "interfaceinheritance.tests 24": +interface Base1 {}; +interface Base2: Base1 {}; +interface Base3: Base1 {}; +interface Derived { + [optional] interface Base2; + [optional] interface Base3; +}; + + +EXPECT SUCCESS "interfaceinheritance.tests 25": +interface Base {}; +interface Derived { + [optional] interface Base; +}; + + +EXPECT FAILURE "interfaceinheritance.tests 26": +interface Base; +interface Derived { + interface Base; +}; + + +EXPECT FAILURE "interfaceinheritance.tests 27": +interface Base; +interface Derived { + [optional] interface Base; +}; + + +EXPECT FAILURE "interfaceinheritance.tests 28": +interface Base {}; +typedef Base Hidden; +interface Derived { + interface Base; + interface Hidden; +}; + + +EXPECT FAILURE "interfaceinheritance.tests 29": +interface Base {}; +typedef Base Hidden; +interface Derived { + interface Hidden; + interface Base; +}; diff --git a/idlc/test/parser/makefile.mk b/idlc/test/parser/makefile.mk new file mode 100644 index 000000000000..ae924e9ed7f9 --- /dev/null +++ b/idlc/test/parser/makefile.mk @@ -0,0 +1,55 @@ +#************************************************************************* +# +# 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 := idlc +TARGET := test_parser + +.INCLUDE: settings.mk +.INCLUDE: target.mk + +ALLTAR: test + +test .PHONY: + $(EXECTEST) attribute.tests $(BIN)/idlc$(EXECPOST) \ + -O $(MISC)/$(TARGET) -stdin + $(EXECTEST) constant.tests $(BIN)/idlc$(EXECPOST) \ + -O $(MISC)/$(TARGET) -stdin + $(EXECTEST) constructor.tests $(BIN)/idlc$(EXECPOST) \ + -O $(MISC)/$(TARGET) -stdin + $(EXECTEST) interfaceinheritance.tests $(BIN)/idlc$(EXECPOST) \ + -O $(MISC)/$(TARGET) -stdin + $(EXECTEST) methodoverload.tests $(BIN)/idlc$(EXECPOST) \ + -O $(MISC)/$(TARGET) -stdin + $(EXECTEST) polystruct.tests $(BIN)/idlc$(EXECPOST) \ + -O $(MISC)/$(TARGET) -stdin + $(EXECTEST) published.tests $(BIN)/idlc$(EXECPOST) \ + -O $(MISC)/$(TARGET) -stdin + $(EXECTEST) struct.tests $(BIN)/idlc$(EXECPOST) \ + -O $(MISC)/$(TARGET) -stdin + $(EXECTEST) typedef.tests $(BIN)/idlc$(EXECPOST) \ + -O $(MISC)/$(TARGET) -stdin diff --git a/idlc/test/parser/methodoverload.tests b/idlc/test/parser/methodoverload.tests new file mode 100644 index 000000000000..33c2c438ba17 --- /dev/null +++ b/idlc/test/parser/methodoverload.tests @@ -0,0 +1,124 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +EXPECT FAILURE "methodoverload.tests 1": +interface Derived { + void f(); + void f(); +}; + + +EXPECT FAILURE "methodoverload.tests 2": +interface Base { + void f(); +}; +interface Derived { + interface Base; + void f(); +}; + + +EXPECT FAILURE "methodoverload.tests 3": +interface Base { + void f(); +}; +interface Derived { + void f(); + interface Base; +}; + + +EXPECT FAILURE "methodoverload.tests 4": +interface Base { + void f(); +}; +interface Derived { + [optional] interface Base; + void f(); +}; + + +EXPECT FAILURE "methodoverload.tests 5": +interface Base { + void f(); +}; +interface Derived { + void f(); + [optional] interface Base; +}; + + +EXPECT FAILURE "methodoverload.tests 6": +interface Base1 { + void f(); +}; +interface Base2 { + void f(); +}; +interface Derived { + interface Base1; + interface Base2; +}; + + +EXPECT FAILURE "methodoverload.tests 7": +interface Base1 { + void f(); +}; +interface Base2 { + void f(); +}; +interface Derived { + [optional] interface Base1; + interface Base2; +}; + + +EXPECT FAILURE "methodoverload.tests 8": +interface Base1 { + void f(); +}; +interface Base2 { + void f(); +}; +interface Derived { + interface Base1; + [optional] interface Base2; +}; + + +EXPECT SUCCESS "methodoverload.tests 9": +interface Base1 { + void f(); +}; +interface Base2 { + void f(); +}; +interface Derived { + [optional] interface Base1; + [optional] interface Base2; +}; diff --git a/idlc/test/parser/polystruct.tests b/idlc/test/parser/polystruct.tests new file mode 100644 index 000000000000..b5661cab6428 --- /dev/null +++ b/idlc/test/parser/polystruct.tests @@ -0,0 +1,255 @@ +#************************************************************************* +# +# 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. +# +#************************************************************************* + +EXPECT SUCCESS "polystruct.tests 1": +struct Struct<T> { T member; }; + + +EXPECT FAILURE "polystruct.tests 2": +struct Struct<T,U,T,V> { long member; }; + + +EXPECT FAILURE "polystruct.tests 3": +struct Struct<T> { long member; }; +typedef Struct Typedef; + + +EXPECT FAILURE "polystruct.tests 4": +struct Struct<T> { long member; }; +typedef Struct<long> Typedef; + + +EXPECT SUCCESS "polystruct.tests 5": +struct Struct<T> { long member; }; + + +EXPECT SUCCESS "polystruct.tests 6": +struct Struct1<T> { T member; }; +struct Struct2 { Struct1<long> member; }; + + +EXPECT SUCCESS "polystruct.tests 7": +struct Struct1<T> { T member; }; +struct Struct2 { Struct1<Struct1<string> > member; }; + + +EXPECT FAILURE "polystruct.tests 8": +struct Struct1<T> { T member; }; +struct Struct2 { Struct1<int> member; }; + + +EXPECT FAILURE "polystruct.tests 9": +struct Struct1<T> { T member; }; +struct Struct2 { Struct1<long,long> member; }; + + +EXPECT FAILURE "polystruct.tests 10": +struct Struct2 { Struct1<long> member; }; + + +EXPECT FAILURE "polystruct.tests 11": +struct Struct1<T> { T member; }; +struct Struct2 { Struct1<> member; }; + + +EXPECT FAILURE "polystruct.tests 12": +struct Struct1<T> { T member; }; +struct Struct2 { Struct1<void> member; }; + + +EXPECT FAILURE "polystruct.tests 13": +exception Exception {}; +struct Struct1<T> { T member; }; +struct Struct2 { Struct1<Exception> member; }; + + +EXPECT SUCCESS "polystruct.tests 14": +struct Struct<T> { T T; }; + + +EXPECT SUCCESS "polystruct.tests 15": +struct Struct<Struct> { Struct member; }; + + +EXPECT FAILURE "polystruct.tests 16": +struct Struct<Struct> { Struct<long> member; }; + + +EXPECT FAILURE "polystruct.tests 17": +struct Struct<Struct> { ::Struct member; }; + + +EXPECT FAILURE "polystruct.tests 18": +struct Struct<Struct> { ::Struct<long> member; }; + + +EXPECT SUCCESS "polystruct.tests 19": +struct Struct1<T> { T member; }; +struct Struct2<Struct1> { Struct1 member; }; + + +EXPECT SUCCESS "polystruct.tests 20": +struct Struct1<T> { T member; }; +struct Struct2<Struct1> { Struct1<long> member; }; + + +EXPECT SUCCESS "polystruct.tests 21": +struct Struct1<T> { T member; }; +struct Struct2<Struct1> { ::Struct1<long> member; }; + + +EXPECT FAILURE "polystruct.tests 22": +struct Struct1 { long member1; }; +struct Struct2<T>: Struct1 { long member2; }; + + +EXPECT FAILURE "polystruct.tests 23": +struct Struct1<T> { long member1; }; +struct Struct2: Struct1<long> { long member2; }; + + +EXPECT FAILURE "polystruct.tests 24": +struct Struct1<T> { long member1; }; +struct Struct2<T>: Struct1<long> { long member2; }; + + +EXPECT FAILURE "polystruct.tests 25": +struct Struct1<T> { long member; }; +struct Struct2 { Struct1<Struct2> member; }; + + +EXPECT FAILURE "polystruct.tests 26": +struct Struct1<T> { long member; }; +struct Struct2<T> { long member; }; +struct Struct3 { Struct1<Struct2<Struct3> > member; }; + + +EXPECT SUCCESS "polystruct.tests 27": +struct Struct1<T> { long member; }; +struct Struct2 { Struct1<sequence<Struct2> > member; }; + + +EXPECT SUCCESS "polystruct.tests 28": +struct Struct1<T> { long member; }; +struct Struct2 { Struct1<sequence<sequence<Struct2> > > member; }; + + +EXPECT SUCCESS "polystruct.tests 29": +struct Struct1<T> { long member; }; +struct Struct2 { sequence<Struct1<Struct2> > member; }; + + +EXPECT SUCCESS "polystruct.tests 30": +struct Struct1<T> { long member; }; +struct Struct2 { sequence<Struct1<sequence<Struct2> > > member; }; + + +EXPECT SUCCESS "polystruct.tests 31": +struct Struct1<T> { long member; }; +struct Struct2 { sequence<sequence<Struct1<Struct2> > > member; }; + + +EXPECT FAILURE "polystruct.tests 32": +struct Struct<T> { Struct member; }; + + +EXPECT FAILURE "polystruct.tests 33": +struct Struct<T> { Struct<long> member; }; + + +EXPECT FAILURE "polystruct.tests 34": +struct Struct<T> { Struct<Struct> member; }; + + +EXPECT FAILURE "polystruct.tests 35": +struct Struct<T> { Struct<Struct<long> > member; }; + + +EXPECT FAILURE "polystruct.tests 36": +struct Struct1<T> { long member; }; +struct Struct2<T> { Struct1<Struct2> member; }; + + +EXPECT FAILURE "polystruct.tests 37": +struct Struct1<T> { long member; }; +struct Struct2<T> { long member; }; +struct Struct3<T> { Struct1<Struct2<Struct3> > member; }; + + +EXPECT FAILURE "polystruct.tests 38": +struct Struct1<T> { long member; }; +struct Struct2<T> { Struct1<Struct2<long> > member; }; + + +EXPECT FAILURE "polystruct.tests 39": +struct Struct1<T> { long member; }; +struct Struct2<T> { long member; }; +struct Struct3<T> { Struct1<Struct2<Struct3<long> > > member; }; + + +EXPECT FAILURE "polystruct.tests 40": +struct Struct1<T> { long member; }; +struct Struct2 { Struct1<unsigned short> member; }; + + +EXPECT FAILURE "polystruct.tests 41": +struct Struct1<T, U> { long member; }; +struct Struct2<T> { long member; }; +struct Struct3 { Struct2<Struct1<long, unsigned long> > member; }; + + +EXPECT FAILURE "polystruct.tests 42": +struct Struct<T> { long member; }; +interface X { void f([in] Struct<unsigned hyper> p); }; + + +EXPECT FAILURE "polystruct.tests 43": +struct Struct1<T> { long member; }; +struct Struct2 { Struct1<sequence<unsigned short> > member; }; + + +EXPECT SUCCESS "polystruct.tests 44": +struct Struct1<T> { long member; }; +struct Struct2 { Struct1<sequence<char> > member; }; + + +EXPECT FAILURE "polystruct.tests 45": +struct Struct1<T> { long member; }; +typedef unsigned short td; +struct Struct2 { Struct1<td> member; }; + + +EXPECT FAILURE "polystruct.tests 46": +struct Struct1<T> { long member; }; +typedef sequence<unsigned short> td; +struct Struct2 { Struct1<td> member; }; + + +EXPECT FAILURE "polystruct.tests 47": +struct Struct1<T> { long member; }; +typedef unsigned short td; +struct Struct2 { Struct1<sequence<td> > member; }; diff --git a/idlc/test/parser/published.tests b/idlc/test/parser/published.tests new file mode 100644 index 000000000000..c3999e58ba88 --- /dev/null +++ b/idlc/test/parser/published.tests @@ -0,0 +1,708 @@ +#************************************************************************* +# +# 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. +# +#************************************************************************* + +EXPECT SUCCESS "published.tests 1": +published enum Enum { VALUE }; +published struct Struct1 { long member; }; +published struct Struct2<T> { T member; }; +published exception E1 {}; +published interface I1 {}; +published typedef long Typedef; +published const long Constant = 1; +published constants Constants { const long Constant = 1; }; +published service Service1: I1 {}; +published service Service2 { interface I1; }; +published singleton Singleton1: I1; +published singleton Singleton2 { service Service2; }; + + +EXPECT FAILURE "published.tests 2": +constants Constants { published const long C = 1; }; + + +EXPECT FAILURE "published.tests 3": +published constants Constants { published const long C = 1; }; + + +EXPECT FAILURE "published.tests 4": +published module m {}; + + +EXPECT SUCCESS "published.tests 5": +interface I1; +interface I1 {}; + + +EXPECT SUCCESS "published.tests 6": +interface I1; +published interface I1 {}; + + +EXPECT FAILURE "published.tests 7": +published interface I1; +interface I1 {}; + + +EXPECT SUCCESS "published.tests 8": +published interface I1; +published interface I1 {}; + + +EXPECT SUCCESS "published.tests 9": +struct S1 { long m1; }; +struct S2: S1 { long m2; }; + + +EXPECT FAILURE "published.tests 10": +struct S1 { long m1; }; +published struct S2: S1 { long m2; }; + + +EXPECT SUCCESS "published.tests 11": +published struct S1 { long m1; }; +struct S2: S1 { long m2; }; + + +EXPECT SUCCESS "published.tests 12": +published struct S1 { long m1; }; +published struct S2: S1 { long m2; }; + + +EXPECT SUCCESS "published.tests 13": +enum E { V }; +struct S1<T> { T m1; }; +struct S2 { S1<E> m2; }; + + +EXPECT FAILURE "published.tests 14": +enum E { V }; +struct S1<T> { T m1; }; +published struct S2 { S1<E> m2; }; + + +EXPECT SUCCESS "published.tests 15": +enum E { V }; +published struct S1<T> { T m1; }; +struct S2 { S1<E> m2; }; + + +EXPECT FAILURE "published.tests 16": +enum E { V }; +published struct S1<T> { T m1; }; +published struct S2 { S1<E> m2; }; + + +EXPECT SUCCESS "published.tests 17": +published enum E { V }; +struct S1<T> { T m1; }; +struct S2 { S1<E> m2; }; + + +EXPECT FAILURE "published.tests 18": +published enum E { V }; +struct S1<T> { T m1; }; +published struct S2 { S1<E> m2; }; + + +EXPECT SUCCESS "published.tests 19": +published enum E { V }; +published struct S1<T> { T m1; }; +struct S2 { S1<E> m2; }; + + +EXPECT SUCCESS "published.tests 20": +published enum E { V }; +published struct S1<T> { T m1; }; +published struct S2 { S1<E> m2; }; + + +EXPECT SUCCESS "published.tests 21": +module com { module sun { module star { module uno { +exception Exception {}; +exception E2: Exception {}; +}; }; }; }; + + +EXPECT FAILURE "published.tests 22": +module com { module sun { module star { module uno { +exception Exception {}; +published exception E2: Exception {}; +}; }; }; }; + + +EXPECT SUCCESS "published.tests 23": +module com { module sun { module star { module uno { +published exception Exception {}; +exception E2: Exception {}; +}; }; }; }; + + +EXPECT SUCCESS "published.tests 24": +module com { module sun { module star { module uno { +published exception Exception {}; +published exception E2: Exception {}; +}; }; }; }; + + +EXPECT SUCCESS "published.tests 25": +enum E { V }; +module com { module sun { module star { module uno { +exception Exception { E m; }; +}; }; }; }; + + +EXPECT FAILURE "published.tests 26": +enum E { V }; +module com { module sun { module star { module uno { +published exception Exception { E m; }; +}; }; }; }; + + +EXPECT SUCCESS "published.tests 27": +published enum E { V }; +module com { module sun { module star { module uno { +exception Exception { E m; }; +}; }; }; }; + + +EXPECT SUCCESS "published.tests 28": +published enum E { V }; +module com { module sun { module star { module uno { +published exception Exception { E m; }; +}; }; }; }; + + +EXPECT SUCCESS "published.tests 29": +interface I1 {}; +interface I2: I1 {}; + + +EXPECT FAILURE "published.tests 30": +interface I1 {}; +published interface I2: I1 {}; + + +EXPECT SUCCESS "published.tests 31": +published interface I1 {}; +interface I2: I1 {}; + + +EXPECT SUCCESS "published.tests 32": +published interface I1 {}; +published interface I2: I1 {}; + + +EXPECT SUCCESS "published.tests 33": +enum E { V }; +interface I1 { [attribute] E m; }; + + +EXPECT FAILURE "published.tests 34": +enum E { V }; +published interface I1 { [attribute] E m; }; + + +EXPECT SUCCESS "published.tests 35": +published enum E { V }; +interface I1 { [attribute] E m; }; + + +EXPECT SUCCESS "published.tests 36": +published enum E { V }; +published interface I1 { [attribute] E m; }; + + +EXPECT SUCCESS "published.tests 36a.1": +module com { module sun { module star { module uno { +exception Exception {}; +interface I1 { [attribute] long m { get raises (Exception); }; }; +}; }; }; }; + + +EXPECT FAILURE "published.tests 36a.2": +module com { module sun { module star { module uno { +exception Exception {}; +published interface I1 { + [attribute] long m { get raises (Exception); }; }; +}; }; }; }; + + +EXPECT SUCCESS "published.tests 36a.3": +module com { module sun { module star { module uno { +published exception Exception {}; +interface I1 { [attribute] long m { get raises (Exception); }; }; +}; }; }; }; + + +EXPECT SUCCESS "published.tests 36a.4": +module com { module sun { module star { module uno { +published exception Exception {}; +published interface I1 { + [attribute] long m { get raises (Exception); }; }; +}; }; }; }; + + +EXPECT SUCCESS "published.tests 37": +enum E { V }; +interface I1 { E f(); }; + + +EXPECT FAILURE "published.tests 38": +enum E { V }; +published interface I1 { E f(); }; + + +EXPECT SUCCESS "published.tests 39": +published enum E { V }; +interface I1 { E f(); }; + + +EXPECT SUCCESS "published.tests 40": +published enum E { V }; +published interface I1 { E f(); }; + + +EXPECT SUCCESS "published.tests 41": +enum E { V }; +interface I1 { void f([in] E p); }; + + +EXPECT FAILURE "published.tests 42": +enum E { V }; +published interface I1 { void f([in] E p); }; + + +EXPECT SUCCESS "published.tests 43": +published enum E { V }; +interface I1 { void f([in] E p); }; + + +EXPECT SUCCESS "published.tests 44": +published enum E { V }; +published interface I1 { void f([in] E p); }; + + +EXPECT SUCCESS "published.tests 45": +module com { module sun { module star { module uno { +exception Exception {}; +interface I1 { void f() raises (Exception); }; +}; }; }; }; + + +EXPECT FAILURE "published.tests 46": +module com { module sun { module star { module uno { +exception Exception {}; +published interface I1 { void f() raises (Exception); }; +}; }; }; }; + + +EXPECT SUCCESS "published.tests 47": +module com { module sun { module star { module uno { +published exception Exception {}; +interface I1 { void f() raises (Exception); }; +}; }; }; }; + + +EXPECT SUCCESS "published.tests 48": +module com { module sun { module star { module uno { +published exception Exception {}; +published interface I1 { void f() raises (Exception); }; +}; }; }; }; + + +EXPECT SUCCESS "published.tests 49": +interface I1 {}; +interface I2 { interface I1; }; + + +EXPECT FAILURE "published.tests 50": +interface I1 {}; +published interface I2 { interface I1; }; + + +EXPECT SUCCESS "published.tests 51": +published interface I1 {}; +interface I2 { interface I1; }; + + +EXPECT SUCCESS "published.tests 52": +published interface I1 {}; +published interface I2 { interface I1; }; + + +EXPECT SUCCESS "published.tests 57": +enum E { V }; +typedef E T; + + +EXPECT FAILURE "published.tests 58": +enum E { V }; +published typedef E T; + + +EXPECT SUCCESS "published.tests 59": +published enum E { V }; +typedef E T; + + +EXPECT SUCCESS "published.tests 60": +published enum E { V }; +published typedef E T; + + +EXPECT SUCCESS "published.tests 61": +enum E { V }; +typedef E T; +struct S { T m; }; + + +EXPECT FAILURE "published.tests 62": +enum E { V }; +typedef E T; +published struct S { T m; }; + + +EXPECT FAILURE "published.tests 63": +enum E { V }; +published typedef E T; +struct S { T m; }; + + +EXPECT FAILURE "published.tests 64": +enum E { V }; +published typedef E T; +published struct S { T m; }; + + +EXPECT SUCCESS "published.tests 65": +published enum E { V }; +typedef E T; +struct S { T m; }; + + +EXPECT FAILURE "published.tests 66": +published enum E { V }; +typedef E T; +published struct S { T m; }; + + +EXPECT SUCCESS "published.tests 67": +published enum E { V }; +published typedef E T; +struct S { T m; }; + + +EXPECT SUCCESS "published.tests 68": +published enum E { V }; +published typedef E T; +published struct S { T m; }; + + +EXPECT SUCCESS "published.tests 69": +const long C1 = 1; +const long C2 = C1 + 1; + + +EXPECT FAILURE "published.tests 70": +const long C1 = 1; +published const long C2 = C1 + 1; + + +EXPECT SUCCESS "published.tests 71": +published const long C1 = 1; +const long C2 = C1 + 1; + + +EXPECT SUCCESS "published.tests 72": +published const long C1 = 1; +published const long C2 = C1 + 1; + + +EXPECT SUCCESS "published.tests 73": +constants Cs { + const long C1 = 1; + const long C2 = C1 + 1; +}; + + +EXPECT SUCCESS "published.tests 74": +published constants Cs { + const long C1 = 1; + const long C2 = C1 + 1; +}; + + +EXPECT SUCCESS "published.tests 75": +constants Cs { const long C1 = 1; }; +const long C2 = Cs::C1 + 1; + + +EXPECT FAILURE "published.tests 76": +constants Cs { const long C1 = 1; }; +published const long C2 = Cs::C1 + 1; + + +EXPECT SUCCESS "published.tests 77": +published constants Cs { const long C1 = 1; }; +const long C2 = Cs::C1 + 1; + + +EXPECT SUCCESS "published.tests 78": +published constants Cs { const long C1 = 1; }; +published const long C2 = Cs::C1 + 1; + + +EXPECT SUCCESS "published.tests 79": +const long C1 = 1; +constants Cs { const long C2 = C1 + 1; }; + + +EXPECT FAILURE "published.tests 80": +const long C1 = 1; +published constants Cs { const long C2 = C1 + 1; }; + + +EXPECT SUCCESS "published.tests 81": +published const long C1 = 1; +constants Cs { const long C2 = C1 + 1; }; + + +EXPECT SUCCESS "published.tests 82": +published const long C1 = 1; +published constants Cs { const long C2 = C1 + 1; }; + + +EXPECT SUCCESS "published.tests 83": +constants Cs1 { const long C1 = 1; }; +constants Cs2 { const long C2 = Cs1::C1 + 1; }; + + +EXPECT FAILURE "published.tests 84": +constants Cs1 { const long C1 = 1; }; +published constants Cs2 { const long C2 = Cs1::C1 + 1; }; + + +EXPECT SUCCESS "published.tests 85": +published constants Cs1 { const long C1 = 1; }; +constants Cs2 { const long C2 = Cs1::C1 + 1; }; + + +EXPECT SUCCESS "published.tests 86": +published constants Cs1 { const long C1 = 1; }; +published constants Cs2 { const long C2 = Cs1::C1 + 1; }; + + +EXPECT SUCCESS "published.tests 87": +typedef long T; +const T C = 1; + + +EXPECT FAILURE "published.tests 88": +typedef long T; +published const T C = 1; + + +EXPECT SUCCESS "published.tests 89": +published typedef long T; +const T C = 1; + + +EXPECT SUCCESS "published.tests 90": +published typedef long T; +published const T C = 1; + + +EXPECT SUCCESS "published.tests 91": +service S1 {}; +service S2 { service S1; }; + + +EXPECT FAILURE "published.tests 92": +service S1 {}; +published service S2 { service S1; }; + + +EXPECT SUCCESS "published.tests 93": +published service S1 {}; +service S2 { service S1; }; + + +EXPECT SUCCESS "published.tests 94": +published service S1 {}; +published service S2 { service S1; }; + + +EXPECT SUCCESS "published.tests 95": +interface I1 {}; +service S { interface I1; }; + + +EXPECT FAILURE "published.tests 96": +interface I1 {}; +published service S { interface I1; }; + + +EXPECT SUCCESS "published.tests 97": +published interface I1 {}; +service S { interface I1; }; + + +EXPECT SUCCESS "published.tests 98": +published interface I1 {}; +published service S { interface I1; }; + + +EXPECT SUCCESS "published.tests 99": +interface I1 {}; +service S: I1; + + +EXPECT FAILURE "published.tests 100": +interface I1 {}; +published service S: I1; + + +EXPECT SUCCESS "published.tests 101": +published interface I1 {}; +service S: I1; + + +EXPECT SUCCESS "published.tests 102": +published interface I1 {}; +published service S: I1; + + +EXPECT SUCCESS "published.tests 103": +enum E { V }; +interface I1 {}; +service S: I1 { + f([in] E p); +}; + + +EXPECT FAILURE "published.tests 104": +enum E { V }; +published interface I1 {}; +published service S: I1 { + f([in] E p); +}; + + +EXPECT SUCCESS "published.tests 105": +published enum E { V }; +interface I1 {}; +service S: I1 { + f([in] E p); +}; + + +EXPECT SUCCESS "published.tests 106": +published enum E { V }; +published interface I1 {}; +published service S: I1 { + f([in] E p); +}; + + +EXPECT SUCCESS "published.tests 107": +module com { module sun { module star { module uno { +exception Exception {}; +interface I1 {}; +service S: I1 { + f() raises (Exception); +}; +}; }; }; }; + + +EXPECT FAILURE "published.tests 108": +module com { module sun { module star { module uno { +exception Exception {}; +published interface I1 {}; +published service S: I1 { + f() raises (Exception); +}; +}; }; }; }; + + +EXPECT SUCCESS "published.tests 109": +module com { module sun { module star { module uno { +published exception Exception {}; +interface I1 {}; +service S: I1 { + f() raises (Exception); +}; +}; }; }; }; + + +EXPECT SUCCESS "published.tests 110": +module com { module sun { module star { module uno { +published exception Exception {}; +published interface I1 {}; +published service S: I1 { + f() raises (Exception); +}; +}; }; }; }; + + +EXPECT SUCCESS "published.tests 111": +service S1 {}; +singleton S2 { service S1; }; + + +EXPECT FAILURE "published.tests 112": +service S1 {}; +published singleton S2 { service S1; }; + + +EXPECT SUCCESS "published.tests 113": +published service S1 {}; +singleton S2 { service S1; }; + + +EXPECT SUCCESS "published.tests 114": +published service S1 {}; +published singleton S2 { service S1; }; + + +EXPECT SUCCESS "published.tests 115": +interface I1 {}; +singleton S: I1; + + +EXPECT FAILURE "published.tests 116": +interface I1 {}; +published singleton S: I1; + + +EXPECT SUCCESS "published.tests 117": +published interface I1 {}; +singleton S: I1; + + +EXPECT SUCCESS "published.tests 118": +published interface I1 {}; +published singleton S: I1; diff --git a/idlc/test/parser/struct.tests b/idlc/test/parser/struct.tests new file mode 100644 index 000000000000..2ddcc7db5cb2 --- /dev/null +++ b/idlc/test/parser/struct.tests @@ -0,0 +1,55 @@ +#************************************************************************* +# +# 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. +# +#************************************************************************* + +EXPECT FAILURE "struct.tests 1": +struct S { void m; }; + + +EXPECT FAILURE "struct.tests 2": +struct S { sequence<void> m; }; + + +EXPECT FAILURE "struct.tests 3": +exception E {}; +struct S { E m; }; + + +EXPECT FAILURE "struct.tests 4": +exception E {}; +struct S { sequence<E> m; }; + + +EXPECT FAILURE "struct.tests 5": +struct S { S m; }; + + +EXPECT SUCCESS "struct.tests 6": +struct S { sequence<S> m; }; + + +EXPECT SUCCESS "struct.tests 7": +struct S { sequence<sequence<S> > m; }; diff --git a/idlc/test/parser/typedef.tests b/idlc/test/parser/typedef.tests new file mode 100644 index 000000000000..f7d2e63f5933 --- /dev/null +++ b/idlc/test/parser/typedef.tests @@ -0,0 +1,67 @@ +#************************************************************************* +# +# 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. +# +#************************************************************************* + +EXPECT SUCCESS "typedef.tests 1": +struct Struct1 { long member1; }; +typedef Struct1 T1; +typedef T1 T2; +struct Struct2: T2 { long member2; }; + + +EXPECT FAILURE "typedef.tests 2": +typedef long T1; +typedef T1 T2; +struct Struct: T2 { long member2; }; + + +EXPECT SUCCESS "typedef.tests 3": +interface Interface1 {}; +typedef Interface1 T1; +typedef T1 T2; +interface Interface2: T2 {}; + + +EXPECT FAILURE "typedef.tests 4": +interface Interface1; +typedef Interface1 T1; +typedef T1 T2; +interface Interface2: T2 {}; + + +EXPECT FAILURE "typedef.tests 5": +typedef long T1; +typedef T1 T2; +interface Interface: T2 {}; + + +EXPECT FAILURE "typedef.tests 6": +typedef void T; + + +EXPECT FAILURE "typedef.tests 7": +exception E {}; +typedef E T; diff --git a/idlc/test/service.idl b/idlc/test/service.idl new file mode 100644 index 000000000000..5a962d8fe948 --- /dev/null +++ b/idlc/test/service.idl @@ -0,0 +1,44 @@ +#include <interface.idl> + +module idlc +{ +module test +{ + +exception bla +{ +}; + +service IdlTest +{ +// [property] bla p0; + [property] short p1; + [optional, property] unsigned short p2; + + [maybevoid, property] long p3; + [bound, property] unsigned long p4; + + [constrained, property] hyper p5; + [transient, property] unsigned hyper p6; + + [maybeambiguous, property] string p7; + [maybedefault, property] type p8; + [removable, property] any p9; + + [readonly, optional, removable, property] ::idlc::test::BaseStruct p10; + + interface XTestBaseTypes; + [optional] interface ::idlc::test::XTestComplexTypes; +}; + +service BetterIdlTest +{ + service IdlTest; + + interface XTestBaseTypes; + [optional] interface ::idlc::test::XTestComplexTypes; +}; + +}; +}; + diff --git a/idlc/test/singleton.idl b/idlc/test/singleton.idl new file mode 100644 index 000000000000..a4b2590c726a --- /dev/null +++ b/idlc/test/singleton.idl @@ -0,0 +1,41 @@ +#include <interface.idl> + +module idlc +{ +module test +{ + +exception bla +{ +}; + +service IdlTest +{ +// [property] bla p0; + [property] short p1; + [optional, property] unsigned short p2; + + [maybevoid, property] long p3; + [bound, property] unsigned long p4; + + [constrained, property] hyper p5; + [transient, property] unsigned hyper p6; + + [maybeambiguous, property] string p7; + [maybedefault, property] type p8; + [removable, property] any p9; + + [readonly, optional, removable, property] ::idlc::test::BaseStruct p10; + + interface XTestBaseTypes; + [optional] interface ::idlc::test::XTestComplexTypes; +}; + +singleton SingletonTest +{ + service IdlTest; +}; + +}; +}; + diff --git a/idlc/test/struct.idl b/idlc/test/struct.idl new file mode 100644 index 000000000000..887b45c7859b --- /dev/null +++ b/idlc/test/struct.idl @@ -0,0 +1,107 @@ +/* In this file the idl struct will be tested. + bla + */ + +/// idlc defines a test module +module idlc +{ + +/// test defines a test module +module test +{ + +typedef sequence< long > Id; +//struct Bla +//{ +// long bla; +//}; + +/** bla + BaseStruct defines an * intial struct + */ +struct BaseStruct +{ + Id Id; + + /// a short member + short m1; + + /// a unsigned short member + unsigned short m2; + + /// a long member + long m3; + + /// a unsigned long member + unsigned long m4; + + /// a hyper member + hyper m5; + + /// a unsigned hyper member + unsigned hyper m6; + + /// a string member + string m7; + + /// a byte member + byte m8; + + /// a type member + type m9; + + /// a float member + float m10; + + /// a double member + double m11; + + /// a char member + char m12; + + /// a boolean member + boolean m13; + + /// a any member + any m14; +}; + +interface XTestBaseTypes; + +typedef sequence< long > LongSeq; + +typedef sequence< LongSeq > LongSeqSeq; + +/** TestStruct deinfes a struct which inherits + from the base strcut type BaseStruct. +*/ +struct TestStruct : BaseStruct +{ + /// a sequence< long > member + sequence< long > ms1; + + /// a sequence< sequence< long > > member + sequence< sequence< long > > ms2; + + /// a long array member with dimesion 5,10 +// long ms3[5][10]; + + /// a string array member with dimension 4,8 +// long[5][10] ms4; + + /// an interface member + XTestBaseTypes ms5; + + /// a typedef member + LongSeq ms6; + + /// a further typedef member + LongSeqSeq ms7; + + /// a sequence typedef member + sequence<LongSeq> ms8; + +}; + +}; }; + diff --git a/idlc/test/typelookup.idl b/idlc/test/typelookup.idl new file mode 100644 index 000000000000..ba1b6f29e8f3 --- /dev/null +++ b/idlc/test/typelookup.idl @@ -0,0 +1,63 @@ +/* In this file the idl struct will be tested. + bla + */ + +#include <enum.idl> + +typedef short Error; + +/// idlc defines a test module +module idlc +{ + +typedef long Error; + +/// test defines a test module +module test +{ + +/** bla + BaseStruct defines an * intial struct + */ +struct BaseStruct +{ + /// a long member + long m1; + /// a string member + string m2; + /// a byte member + byte m3; + /// a type member + type m4; + /// a enum member, Error in moudle idlc::test + Error m5; + /// a typedef member, global Error (typedef short) + ::Error m6; + /// a typedef member, Error in moudle idlc (typedef long) + ::idlc::Error m7; + /// a typedef member, Error in moudle idlc (typedef long) + idlc::Error m8; + /// a enum member, Error in moudle idlc::test + test::Error m9; +}; + +/** TestStruct deinfes a struct which inherits + from the base strcut type BaseStruct. +*/ +struct TestStruct : BaseStruct +{ + /// a short member + short ms1; + /// a hyper member + hyper ms2; + /// a sequence<long> member + sequence< long > ms3; + /// a long array member with dimesion 5,10 + long ms4[5][10]; + /// a string array member with dimension 4,8 + long[5][10] ms5; +}; + +}; // test + +}; // idlc diff --git a/idlc/test/union.idl b/idlc/test/union.idl new file mode 100644 index 000000000000..8e9b5c5dedf8 --- /dev/null +++ b/idlc/test/union.idl @@ -0,0 +1,35 @@ +module idlc +{ +module test +{ + +union UnionTest switch (long) { + case 1: long x; + case 2: byte y; + case 3: string z; + case 4: + case 5: short w; + case 6: long array[ 10 ][ 20 ]; + case 7: sequence<long> seq; + default: any a; +}; + +typedef enum E { + A, + B +} EAlias; + +// Union with no default label +union U2 switch(EAlias) { + case E::A : long x; + case E::B : short y; +}; + +union U3 switch(char) { + case 2 : long x; + case 4 : short y; +}; + +}; +}; + |