From 940b4d1848e8c70ab7642901a68594e8016caffc Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 27 Apr 2024 18:51:28 +0200 Subject: Adding upstream version 1:7.0.4. Signed-off-by: Daniel Baumann --- idl/Executable_svidl.mk | 56 ++++ idl/Makefile | 14 + idl/Module_idl.mk | 26 ++ idl/README | 7 + idl/inc/basobj.hxx | 129 ++++++++ idl/inc/bastype.hxx | 76 +++++ idl/inc/command.hxx | 47 +++ idl/inc/database.hxx | 140 +++++++++ idl/inc/globals.hxx | 130 ++++++++ idl/inc/hash.hxx | 61 ++++ idl/inc/lex.hxx | 217 ++++++++++++++ idl/inc/module.hxx | 38 +++ idl/inc/object.hxx | 88 ++++++ idl/inc/parser.hxx | 72 +++++ idl/inc/slot.hxx | 136 +++++++++ idl/inc/types.hxx | 119 ++++++++ idl/source/cmptools/hash.cxx | 70 +++++ idl/source/cmptools/lex.cxx | 336 +++++++++++++++++++++ idl/source/objects/basobj.cxx | 143 +++++++++ idl/source/objects/bastype.cxx | 123 ++++++++ idl/source/objects/module.cxx | 39 +++ idl/source/objects/object.cxx | 347 ++++++++++++++++++++++ idl/source/objects/slot.cxx | 651 +++++++++++++++++++++++++++++++++++++++++ idl/source/objects/types.cxx | 322 ++++++++++++++++++++ idl/source/prj/command.cxx | 303 +++++++++++++++++++ idl/source/prj/database.cxx | 541 ++++++++++++++++++++++++++++++++++ idl/source/prj/globals.cxx | 92 ++++++ idl/source/prj/parser.cxx | 590 +++++++++++++++++++++++++++++++++++++ idl/source/prj/svidl.cxx | 215 ++++++++++++++ 29 files changed, 5128 insertions(+) create mode 100644 idl/Executable_svidl.mk create mode 100644 idl/Makefile create mode 100644 idl/Module_idl.mk create mode 100644 idl/README create mode 100644 idl/inc/basobj.hxx create mode 100644 idl/inc/bastype.hxx create mode 100644 idl/inc/command.hxx create mode 100644 idl/inc/database.hxx create mode 100644 idl/inc/globals.hxx create mode 100644 idl/inc/hash.hxx create mode 100644 idl/inc/lex.hxx create mode 100644 idl/inc/module.hxx create mode 100644 idl/inc/object.hxx create mode 100644 idl/inc/parser.hxx create mode 100644 idl/inc/slot.hxx create mode 100644 idl/inc/types.hxx create mode 100644 idl/source/cmptools/hash.cxx create mode 100644 idl/source/cmptools/lex.cxx create mode 100644 idl/source/objects/basobj.cxx create mode 100644 idl/source/objects/bastype.cxx create mode 100644 idl/source/objects/module.cxx create mode 100644 idl/source/objects/object.cxx create mode 100644 idl/source/objects/slot.cxx create mode 100644 idl/source/objects/types.cxx create mode 100644 idl/source/prj/command.cxx create mode 100644 idl/source/prj/database.cxx create mode 100644 idl/source/prj/globals.cxx create mode 100644 idl/source/prj/parser.cxx create mode 100644 idl/source/prj/svidl.cxx (limited to 'idl') diff --git a/idl/Executable_svidl.mk b/idl/Executable_svidl.mk new file mode 100644 index 000000000..fe0933795 --- /dev/null +++ b/idl/Executable_svidl.mk @@ -0,0 +1,56 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you under the Apache +# License, Version 2.0 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.apache.org/licenses/LICENSE-2.0 . +# + +$(eval $(call gb_Executable_Executable,svidl)) + +$(eval $(call gb_Executable_use_external,svidl,boost_headers)) + +ifeq ($(DISABLE_DYNLOADING),TRUE) +$(eval $(call gb_Executable_use_external,svidl,dtoa)) +endif + +$(eval $(call gb_Executable_set_include,svidl,\ + $$(INCLUDE) \ + -I$(SRCDIR)/idl/inc \ +)) + +$(eval $(call gb_Executable_use_sdk_api,svidl)) + +$(eval $(call gb_Executable_use_libraries,svidl,\ + tl \ + sal \ +)) + +$(eval $(call gb_Executable_add_exception_objects,svidl,\ + idl/source/cmptools/hash \ + idl/source/cmptools/lex \ + idl/source/objects/basobj \ + idl/source/objects/bastype \ + idl/source/objects/module \ + idl/source/objects/object \ + idl/source/objects/slot \ + idl/source/objects/types \ + idl/source/prj/command \ + idl/source/prj/database \ + idl/source/prj/globals \ + idl/source/prj/svidl \ + idl/source/prj/parser \ +)) + +# vim: set noet sw=4 ts=4: diff --git a/idl/Makefile b/idl/Makefile new file mode 100644 index 000000000..0997e6284 --- /dev/null +++ b/idl/Makefile @@ -0,0 +1,14 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST)))) + +include $(module_directory)/../solenv/gbuild/partial_build.mk + +# vim: set noet sw=4 ts=4: diff --git a/idl/Module_idl.mk b/idl/Module_idl.mk new file mode 100644 index 000000000..ea476b41c --- /dev/null +++ b/idl/Module_idl.mk @@ -0,0 +1,26 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you under the Apache +# License, Version 2.0 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.apache.org/licenses/LICENSE-2.0 . +# + +$(eval $(call gb_Module_Module,idl)) + +$(eval $(call gb_Module_add_targets_for_build,idl,\ + Executable_svidl \ +)) + +# vim: set noet sw=4 ts=4: diff --git a/idl/README b/idl/README new file mode 100644 index 000000000..b494f10ab --- /dev/null +++ b/idl/README @@ -0,0 +1,7 @@ +SvIDL Compiler that generates C++ slot headers from SDI files in modules' sdi/ +subdirectory. + +There is an overview of basic architecture of the markup of SDI files in the +OOo wiki: + +https://wiki.openoffice.org/wiki/Framework/Article/Implementation_of_the_Dispatch_API_In_SFX2 diff --git a/idl/inc/basobj.hxx b/idl/inc/basobj.hxx new file mode 100644 index 000000000..12def9b70 --- /dev/null +++ b/idl/inc/basobj.hxx @@ -0,0 +1,129 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_IDL_INC_BASOBJ_HXX +#define INCLUDED_IDL_INC_BASOBJ_HXX + +#include +#include "bastype.hxx" +#include +#include + +class SvTokenStream; +class SvIdlDataBase; + +template +class SvRefMemberList : private std::vector +{ +private: + typedef typename std::vector base_t; + +public: + using base_t::size; + using base_t::front; + using base_t::back; + using base_t::operator[]; + using base_t::begin; + using base_t::end; + using typename base_t::iterator; + using typename base_t::const_iterator; + using base_t::rbegin; + using base_t::rend; + using typename base_t::reverse_iterator; + using base_t::empty; + + ~SvRefMemberList() { clear(); } + void clear() + { + for( typename base_t::const_iterator it = base_t::begin(); it != base_t::end(); ++it ) + { + T p = *it; + if( p ) + p->ReleaseRef(); + } + base_t::clear(); + } + + void push_back( T p ) + { + base_t::push_back( p ); + p->AddFirstRef(); + } + + void insert( typename base_t::iterator it, T p ) + { + base_t::insert( it, p ); + p->AddFirstRef(); + } + + void pop_back() + { + T p = base_t::back(); + base_t::pop_back(); + if( p ) + p->ReleaseRef(); + } +}; + +class SvMetaObject : public SvRefBase +{ + OString aName; + +protected: + bool ReadNameSvIdl( SvTokenStream & rInStm ); + void DoReadContextSvIdl( SvIdlDataBase &, SvTokenStream & rInStm ); + virtual void ReadContextSvIdl( SvIdlDataBase &, SvTokenStream & rInStm ); + virtual void ReadAttributesSvIdl( SvIdlDataBase & rBase, + SvTokenStream & rInStm ); +public: + SvMetaObject(); + + static void WriteTab( SvStream & rOutStm, sal_uInt16 nTab ); + static void Back2Delimiter( SvStream & ); + static void WriteStars( SvStream & ); + + void SetName( const OString& rName ); + virtual const OString & GetName() const { return aName; } + + virtual bool ReadSvIdl( SvIdlDataBase &, SvTokenStream & rInStm ); +}; + +class SvMetaReference : public SvMetaObject +{ + tools::SvRef aRef; +public: + SvMetaReference(); + + const OString & GetName() const override + { + return ( !aRef.is() + || !SvMetaObject::GetName().isEmpty() ) + ? SvMetaObject::GetName() + : aRef->GetName(); + } + + SvMetaReference * GetRef() const { return aRef.get(); } + void SetRef( SvMetaReference * pRef ) + { aRef = pRef; } +}; + +#endif // INCLUDED_IDL_INC_BASOBJ_HXX + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/idl/inc/bastype.hxx b/idl/inc/bastype.hxx new file mode 100644 index 000000000..1c0d93765 --- /dev/null +++ b/idl/inc/bastype.hxx @@ -0,0 +1,76 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_IDL_INC_BASTYPE_HXX +#define INCLUDED_IDL_INC_BASTYPE_HXX + + +#include +#include + +class SvStringHashEntry; +class SvIdlDataBase; +class SvStream; +class SvTokenStream; + +class SvBOOL +{ + bool bVal:1, + bSet:1; +public: + SvBOOL() { bSet = bVal = false; } + SvBOOL( bool b ) : bVal( b ), bSet( false) {} + SvBOOL & operator = ( bool n ) { bVal = n; bSet = true; return *this; } + + operator bool() const { return bVal; } + bool IsSet() const { return bSet; } + + bool ReadSvIdl( SvStringHashEntry const * pName, SvTokenStream & rInStm ); +}; + + +class SvIdentifier +{ + OString m_aStr; + sal_uInt32 nValue; +public: + SvIdentifier() : nValue( 0 ) {}; + SvIdentifier(sal_uInt32 n) : nValue( n ) {}; + + void setString(const OString& rStr) { m_aStr = rStr; } + const OString& getString() const { return m_aStr; } + + void ReadSvIdl( SvStringHashEntry const * pName, SvTokenStream & rInStm ); + bool IsSet() const + { + return !m_aStr.isEmpty() || nValue != 0; + } + sal_uInt32 GetValue() const { return nValue; } + void SetValue( sal_uInt32 bVal ) { nValue = bVal; } + + void ReadSvIdl( SvIdlDataBase &, SvTokenStream & rInStm ); +}; + + +bool ReadStringSvIdl( SvStringHashEntry const * pName, SvTokenStream & rInStm, OString& aString ); + + +#endif // INCLUDED_IDL_INC_BASTYPE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/idl/inc/command.hxx b/idl/inc/command.hxx new file mode 100644 index 000000000..ea5e0f446 --- /dev/null +++ b/idl/inc/command.hxx @@ -0,0 +1,47 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_IDL_INC_COMMAND_HXX +#define INCLUDED_IDL_INC_COMMAND_HXX + +#include +#include + +class SvCommand +{ +public: + std::vector aInFileList; + OUString aSlotMapFile; + OUString aPath; + OUString aTargetFile; + OUString aExportFile; + OUString m_DepFile; + sal_uInt32 nVerbosity; + + SvCommand( int argc, char ** argv ); + ~SvCommand(); +}; + +void Init(); +class SvIdlWorkingBase; +bool ReadIdl( SvIdlWorkingBase * pDataBase, const SvCommand & rCommand ); + +#endif // INCLUDED_IDL_INC_COMMAND_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/idl/inc/database.hxx b/idl/inc/database.hxx new file mode 100644 index 000000000..caf3cf9ff --- /dev/null +++ b/idl/inc/database.hxx @@ -0,0 +1,140 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_IDL_INC_DATABASE_HXX +#define INCLUDED_IDL_INC_DATABASE_HXX + +#include "module.hxx" +#include "hash.hxx" +#include "lex.hxx" +#include + +#include +#include +#include + +class SvCommand; + +class SvIdlError +{ + OString aText; +public: + sal_uInt32 nLine, nColumn; + + SvIdlError() : nLine(0), nColumn(0) {} + SvIdlError( sal_uInt32 nL, sal_uInt32 nC ) + : nLine(nL), nColumn(nC) {} + + const OString& GetText() const { return aText; } + void SetText( const OString& rT ) { aText = rT; } + bool IsError() const { return nLine != 0; } +}; + +class SvParseException final : public std::exception +{ +public: + SvIdlError aError; + SvParseException( SvTokenStream const & rInStm, const OString& rError ); + SvParseException( const OString& rError, SvToken const & rTok ); +}; + + + +class SvIdlDataBase +{ + bool bExport; + OUString aExportFile; + sal_uInt32 nUniqueId; + sal_uInt32 nVerbosity; + std::vector aIdFileList; + std::unique_ptr pIdTable; + + SvRefMemberList aTypeList; + SvRefMemberList aClassList; + SvRefMemberList aModuleList; + SvRefMemberList aSlotList; + SvRefMemberList aContextStack; + +protected: + ::std::set< OUString > m_DepFiles; + OUString aPath; + SvIdlError aError; + void WriteReset() + { + aUsedTypes.clear(); + } +public: + OUString sSlotMapFile; + + explicit SvIdlDataBase( const SvCommand& rCmd ); + ~SvIdlDataBase(); + + SvRefMemberList& GetTypeList(); + SvRefMemberList& GetClassList() { return aClassList; } + SvRefMemberList& GetModuleList() { return aModuleList; } + + // list of used types while writing + SvRefMemberList aUsedTypes; + + void StartNewFile( const OUString& rName ); + void SetExportFile( const OUString& rName ) + { aExportFile = rName; } + void AppendSlot( SvMetaSlot *pSlot ); + const SvIdlError & GetError() const { return aError; } + void SetError( const SvIdlError & r ) + { aError = r; } + + const OUString & GetPath() const { return aPath; } + void SetPath(const OUString &s) { aPath = s; } + SvRefMemberList& GetStack() { return aContextStack; } + + void Write(const OString& rText) const; + void WriteError( SvTokenStream & rInStm ); + void SetError( const OString& rError, SvToken const & rTok ); + void SetAndWriteError( SvTokenStream & rInStm, const OString& rError ); + void Push( SvMetaObject * pObj ); + sal_uInt32 GetUniqueId() { return ++nUniqueId; } + bool FindId( const OString& rIdName, sal_uLong * pVal ); + void InsertId( const OString& rIdName, sal_uLong nVal ); + bool ReadIdFile( const OString& rFileName ); + + SvMetaType * FindType( const OString& rName ); + static SvMetaType * FindType( const SvMetaType *, SvRefMemberList& ); + + SvMetaType * ReadKnownType( SvTokenStream & rInStm ); + SvMetaAttribute * ReadKnownAttr( SvTokenStream & rInStm, + SvMetaType * pType ); + SvMetaAttribute * FindKnownAttr( const SvIdentifier& ); + SvMetaClass * ReadKnownClass( SvTokenStream & rInStm ); + SvMetaClass * FindKnownClass( const OString& aName ); + void AddDepFile(OUString const& rFileName); + void WriteDepFile(SvFileStream & rStream, OUString const& rTarget); +}; + +class SvIdlWorkingBase : public SvIdlDataBase +{ +public: + explicit SvIdlWorkingBase( const SvCommand& rCmd ); + + bool WriteSfx( SvStream & ); +}; + +#endif // INCLUDED_IDL_INC_DATABASE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/idl/inc/globals.hxx b/idl/inc/globals.hxx new file mode 100644 index 000000000..033a8f270 --- /dev/null +++ b/idl/inc/globals.hxx @@ -0,0 +1,130 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_IDL_INC_GLOBALS_HXX +#define INCLUDED_IDL_INC_GLOBALS_HXX + +#include "hash.hxx" +#include + +struct SvGlobalHashNames +{ + SvStringHashEntry* MM_module; + SvStringHashEntry* MM_interface; + SvStringHashEntry* MM_shell; + SvStringHashEntry* MM_Toggle; + SvStringHashEntry* MM_AutoUpdate; + SvStringHashEntry* MM_Asynchron; + SvStringHashEntry* MM_RecordPerSet; + SvStringHashEntry* MM_RecordPerItem; + SvStringHashEntry* MM_NoRecord; + SvStringHashEntry* MM_RecordAbsolute; + SvStringHashEntry* MM_enum; + SvStringHashEntry* MM_UINT16; + SvStringHashEntry* MM_INT16; + SvStringHashEntry* MM_UINT32; + SvStringHashEntry* MM_INT32; + SvStringHashEntry* MM_BOOL; + SvStringHashEntry* MM_BYTE; + SvStringHashEntry* MM_float; + SvStringHashEntry* MM_double; + SvStringHashEntry* MM_item; + SvStringHashEntry* MM_import; + SvStringHashEntry* MM_SlotIdFile; + SvStringHashEntry* MM_include; + SvStringHashEntry* MM_ExecMethod; + SvStringHashEntry* MM_StateMethod; + SvStringHashEntry* MM_GroupId; + SvStringHashEntry* MM_Export; + SvStringHashEntry* MM_define; + SvStringHashEntry* MM_MenuConfig; + SvStringHashEntry* MM_ToolBoxConfig; + SvStringHashEntry* MM_AccelConfig; + SvStringHashEntry* MM_FastCall; + SvStringHashEntry* MM_SbxObject; + SvStringHashEntry* MM_Container; + SvStringHashEntry* MM_ReadOnlyDoc; + SvStringHashEntry* MM_struct; + SvStringHashEntry* MM_DisableFlags; + + SvGlobalHashNames(); +}; + +class IdlDll +{ +public: + std::unique_ptr pHashTable; + std::unique_ptr pGlobalNames; + + IdlDll(); + ~IdlDll(); +}; + +IdlDll & GetIdlApp(); + +#define HASH_INLINE( Name ) \ +inline SvStringHashEntry * SvHash_##Name() \ +{ \ + if( !GetIdlApp().pGlobalNames ) \ + GetIdlApp().pGlobalNames.reset( new SvGlobalHashNames() ); \ + return GetIdlApp().pGlobalNames->MM_##Name; \ +} + +HASH_INLINE(module) +HASH_INLINE(interface) +HASH_INLINE(shell) +HASH_INLINE(Toggle) +HASH_INLINE(AutoUpdate) +HASH_INLINE(Asynchron) +HASH_INLINE(RecordPerItem) +HASH_INLINE(RecordPerSet) +HASH_INLINE(NoRecord) +HASH_INLINE(RecordAbsolute) +HASH_INLINE(enum) +HASH_INLINE(UINT16) +HASH_INLINE(INT16) +HASH_INLINE(UINT32) +HASH_INLINE(INT32) +HASH_INLINE(BOOL) +HASH_INLINE(BYTE) +HASH_INLINE(item) +HASH_INLINE(import) +HASH_INLINE(SlotIdFile) +HASH_INLINE(include) +HASH_INLINE(ExecMethod) +HASH_INLINE(StateMethod) +HASH_INLINE(GroupId) +HASH_INLINE(float) +HASH_INLINE(double) +HASH_INLINE(Export) +HASH_INLINE(define) +HASH_INLINE(MenuConfig) +HASH_INLINE(ToolBoxConfig) +HASH_INLINE(AccelConfig) +HASH_INLINE(FastCall) +HASH_INLINE(SbxObject) +HASH_INLINE(Container) +HASH_INLINE(ReadOnlyDoc) +HASH_INLINE(struct) +HASH_INLINE(DisableFlags) + + +#endif // INCLUDED_IDL_INC_GLOBALS_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/idl/inc/hash.hxx b/idl/inc/hash.hxx new file mode 100644 index 000000000..fb3ba3227 --- /dev/null +++ b/idl/inc/hash.hxx @@ -0,0 +1,61 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_IDL_INC_HASH_HXX +#define INCLUDED_IDL_INC_HASH_HXX + +#include +#include +#include +#include +#include + +class SvStringHashEntry +{ + OString aName; + sal_uLong nValue; +public: + SvStringHashEntry( const OString& rName ) + : aName(rName) + , nValue(0) + { + } + + const OString& GetName() const { return aName; } + + void SetValue( sal_uLong n ) { nValue = n; } + sal_uLong GetValue() const { return nValue; } +}; + +class SvStringHashTable +{ + std::unordered_map> maInt2EntryMap; + std::unordered_map maString2IntMap; + sal_uInt32 mnNextId = 0; + +public: + SvStringHashEntry * Insert( OString const & rElement, sal_uInt32 * pInsertPos ); + bool Test( OString const & rElement, sal_uInt32 * pInsertPos ); + SvStringHashEntry * Get( sal_uInt32 nInsertPos ) const; + OString GetNearString( const OString& rName ) const; +}; + +#endif // INCLUDED_IDL_INC_HASH_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/idl/inc/lex.hxx b/idl/inc/lex.hxx new file mode 100644 index 000000000..b7aa9336d --- /dev/null +++ b/idl/inc/lex.hxx @@ -0,0 +1,217 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_IDL_INC_LEX_HXX +#define INCLUDED_IDL_INC_LEX_HXX + +#include +#include "hash.hxx" +#include +#include +#include + +enum class SVTOKENTYPE { Empty, Comment, + Integer, String, + Bool, Identifier, + Char, + EndOfFile, HashId }; + +class SvToken +{ +friend class SvTokenStream; + sal_uInt64 nLine, nColumn; + SVTOKENTYPE nType; + OString aString; + union + { + sal_uInt64 nLong; + bool bBool; + char cChar; + SvStringHashEntry * pHash; + }; +public: + SvToken(); + SvToken( const SvToken & rObj ) = delete; + + SvToken & operator = ( const SvToken & rObj ); + + OString GetTokenAsString() const; + + void SetLine( sal_uInt64 nLineP ) { nLine = nLineP; } + sal_uInt64 GetLine() const { return nLine; } + + void SetColumn( sal_uInt64 nColumnP ) { nColumn = nColumnP; } + sal_uInt64 GetColumn() const { return nColumn; } + + bool IsComment() const { return nType == SVTOKENTYPE::Comment; } + bool IsInteger() const { return nType == SVTOKENTYPE::Integer; } + bool IsString() const { return nType == SVTOKENTYPE::String; } + bool IsBool() const { return nType == SVTOKENTYPE::Bool; } + bool IsIdentifierHash() const + { return nType == SVTOKENTYPE::HashId; } + bool IsIdentifier() const + { + return nType == SVTOKENTYPE::Identifier + || nType == SVTOKENTYPE::HashId; + } + bool IsChar() const { return nType == SVTOKENTYPE::Char; } + bool IsEof() const { return nType == SVTOKENTYPE::EndOfFile; } + + const OString& GetString() const + { + return IsIdentifierHash() + ? pHash->GetName() + : aString; + } + sal_uInt64 GetNumber() const { return nLong; } + bool GetBool() const { return bBool; } + char GetChar() const { return cChar; } + + void SetHash( SvStringHashEntry * pHashP ) + { pHash = pHashP; nType = SVTOKENTYPE::HashId; } + bool Is( SvStringHashEntry const * pEntry ) const + { return IsIdentifierHash() && pHash == pEntry; } +}; + +inline SvToken::SvToken() + : nLine(0) + , nColumn(0) + , nType( SVTOKENTYPE::Empty ) +{ +} + +class SvTokenStream +{ + sal_uInt64 nLine, nColumn; + sal_Int32 nBufPos; + char c; // next character + static const sal_uInt16 nTabSize = 4; // length of tabulator + OString aStrTrue; + OString aStrFalse; + sal_uInt32 nMaxPos; + + std::unique_ptr pInStream; + OUString aFileName; + std::vector > aTokList; + std::vector >::iterator pCurToken; + + OString aBufStr; + + void InitCtor(); + + char GetNextChar(); + char GetFastNextChar() + { + return (nBufPos < aBufStr.getLength()) + ? aBufStr[nBufPos++] + : '\0'; + } + + void FillTokenList(); + sal_uInt64 GetNumber(); + bool MakeToken( SvToken & ); + bool IsEof() const { return pInStream->eof(); } + void SetMax() + { + sal_uInt32 n = Tell(); + if( n > nMaxPos ) + nMaxPos = n; + } + void CalcColumn() + { + // if end of line spare calculation + if( 0 != c ) + { + sal_Int32 n = 0; + nColumn = 0; + while( n < nBufPos ) + nColumn += aBufStr[n++] == '\t' ? nTabSize : 1; + } + } +public: + SvTokenStream( const OUString & rFileName ); + ~SvTokenStream(); + + const OUString & GetFileName() const { return aFileName; } + SvStream & GetStream() { return *pInStream; } + + SvToken& GetToken_PrevAll() + { + std::vector >::iterator pRetToken = pCurToken; + + // current iterator always valid + if(pCurToken != aTokList.begin()) + --pCurToken; + + return *(*pRetToken); + } + + SvToken& GetToken_Next() + { + std::vector >::iterator pRetToken = pCurToken++; + + if (pCurToken == aTokList.end()) + pCurToken = pRetToken; + + SetMax(); + + return *(*pRetToken); + } + + SvToken& GetToken() const { return *(*pCurToken); } + + bool ReadIf( char cChar ) + { + if( GetToken().IsChar() && cChar == GetToken().GetChar() ) + { + GetToken_Next(); + return true; + } + else + return false; + } + + void ReadIfDelimiter() + { + if( GetToken().IsChar() + && (';' == GetToken().GetChar() + || ',' == GetToken().GetChar()) ) + { + GetToken_Next(); + } + } + + sal_uInt32 Tell() const { return pCurToken-aTokList.begin(); } + + void Seek( sal_uInt32 nPos ) + { + pCurToken = aTokList.begin() + nPos; + SetMax(); + } + + void SeekToMax() + { + pCurToken = aTokList.begin()+nMaxPos; + } +}; + + +#endif // INCLUDED_IDL_INC_LEX_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/idl/inc/module.hxx b/idl/inc/module.hxx new file mode 100644 index 000000000..05587ee96 --- /dev/null +++ b/idl/inc/module.hxx @@ -0,0 +1,38 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_IDL_INC_MODULE_HXX +#define INCLUDED_IDL_INC_MODULE_HXX + +#include "slot.hxx" +#include "object.hxx" + +class SvMetaModule final : public SvMetaObject +{ +public: + SvRefMemberList aClassList; + + SvMetaModule(); + + void WriteSfx( SvIdlDataBase & rBase, SvStream & rOutStm ); +}; + +#endif // INCLUDED_IDL_INC_MODULE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/idl/inc/object.hxx b/idl/inc/object.hxx new file mode 100644 index 000000000..822e562c2 --- /dev/null +++ b/idl/inc/object.hxx @@ -0,0 +1,88 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_IDL_INC_OBJECT_HXX +#define INCLUDED_IDL_INC_OBJECT_HXX + +#include "types.hxx" +#include "slot.hxx" +#include + +class SvMetaClass; +typedef ::std::vector< SvMetaClass* > SvMetaClassList; + +class SvClassElement +{ + OString aPrefix; + tools::SvRef xClass; +public: + SvClassElement(); + SvClassElement(SvMetaClass* pClass) { xClass = pClass; } + + void SetPrefix( const OString& rPrefix ) + { aPrefix = rPrefix; } + const OString& GetPrefix() const + { return aPrefix; } + + void SetClass( SvMetaClass * pClass ) + { xClass = pClass; } + SvMetaClass * GetClass() const + { return xClass.get(); } +}; + + +class SvMetaClass : public SvMetaType +{ +public: + tools::SvRef aSuperClass; + std::vector aClassElementList; + SvRefMemberList aAttrList; + bool TestAttribute( SvIdlDataBase & rBase, SvTokenStream & rInStm, + SvMetaAttribute & rAttr ) const; +private: + + static void WriteSlotStubs( const OString& rShellName, + SvSlotElementList & rSlotList, + std::vector & rList, + SvStream & rOutStm ); + static sal_uInt16 WriteSlotParamArray( SvIdlDataBase & rBase, + SvSlotElementList & rSlotList, + SvStream & rOutStm ); + static sal_uInt16 WriteSlots( const OString& rShellName, + SvSlotElementList & rSlotList, + SvIdlDataBase & rBase, + SvStream & rOutStm ); + + void InsertSlots( SvSlotElementList& rList, std::vector& rSuperList, + SvMetaClassList & rClassList, + const OString& rPrefix, SvIdlDataBase& rBase ); + +public: + SvMetaClass(); + virtual void ReadContextSvIdl( SvIdlDataBase &, + SvTokenStream & rInStm ) override; + + void FillClasses( SvMetaClassList & rList ); + + virtual void WriteSfx( SvIdlDataBase & rBase, SvStream & rOutStm ) override; +}; + +#endif // INCLUDED_IDL_INC_OBJECT_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/idl/inc/parser.hxx b/idl/inc/parser.hxx new file mode 100644 index 000000000..ae9db7105 --- /dev/null +++ b/idl/inc/parser.hxx @@ -0,0 +1,72 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_IDL_INC_PARSER_HXX +#define INCLUDED_IDL_INC_PARSER_HXX + +#include +#include "types.hxx" + +class SvTokenStream; +class SvIdlDataBase; +class SvMetaModule; +class SvMetaTypeEnum; +class SvStringHashEntry; +class SvMetaType; +class SvMetaClass; +class SvBOOL; + +class SvIdlParser +{ + SvIdlDataBase& rBase; + SvTokenStream & rInStm; +public: + SvIdlParser( SvIdlDataBase& rBase_, SvTokenStream & rInStrm_) : rBase(rBase_), rInStm(rInStrm_) {} + void ReadSvIdl( const OUString & rPath ); + void ReadModuleHeader(SvMetaModule& rModule); + void ReadModuleBody(SvMetaModule& rModule); + void ReadModuleElement( SvMetaModule& rModule ); + void ReadInclude( SvMetaModule& rModule ); + void ReadInterfaceOrShell( SvMetaModule& rModule, MetaTypeType aMetaTypeType ); + void ReadInterfaceOrShellEntry( SvMetaClass& rClass ); + bool ReadSlot( SvMetaSlot& rSlot ); + void ReadInterfaceOrShellMethod( SvMetaAttribute& rAttr ); + void ReadItem(); + void ReadStruct(); + void ReadEnum(); + void ReadEnumValue( SvMetaTypeEnum& rEnum ); + void ReadSlotId(SvIdentifier& rSlotId); + void ReadSlotAttribute( SvMetaSlot& rSlot ); + SvMetaClass* ReadKnownClass(); + SvMetaType* ReadKnownType(); + void Read(char cChar); + bool ReadIfBoolAttribute( SvBOOL&, SvStringHashEntry const * pName); + void ReadIfIdAttribute( SvIdentifier& rIdentifier, SvStringHashEntry const * pName ); + bool ReadIf(char cChar); + void ReadDelimiter(); + bool ReadIfDelimiter(); + OString ReadIdentifier(); + OString ReadString(); + void Read(SvStringHashEntry const *); + bool ReadIf(SvStringHashEntry const *); +}; + +#endif // INCLUDED_IDL_INC_PARSER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/idl/inc/slot.hxx b/idl/inc/slot.hxx new file mode 100644 index 000000000..34709bc86 --- /dev/null +++ b/idl/inc/slot.hxx @@ -0,0 +1,136 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_IDL_INC_SLOT_HXX +#define INCLUDED_IDL_INC_SLOT_HXX + +#include "types.hxx" +#include "command.hxx" + +class SvMetaSlot : public SvMetaAttribute +{ +public: + SvIdentifier aGroupId; + SvIdentifier aExecMethod; + SvIdentifier aStateMethod; + + SvBOOL aToggle; + SvBOOL aAutoUpdate; + + SvBOOL aAsynchron; + + SvBOOL aRecordPerItem;// exclusive + SvBOOL aRecordPerSet; + SvBOOL aNoRecord; + SvBOOL aRecordAbsolute; + + SvBOOL aMenuConfig; + SvBOOL aToolBoxConfig; + SvBOOL aAccelConfig; + SvBOOL aFastCall; + SvBOOL aContainer; + OString aDisableFlags; + SvMetaSlot* pNextSlot; + sal_uLong nListPos; + SvBOOL aReadOnlyDoc; + SvBOOL aExport; + + void WriteSlot( const OString& rShellName, + sal_uInt16 nCount, const OString& rSlotId, + SvSlotElementList &rList, + size_t nStart, + SvIdlDataBase & rBase, SvStream & rOutStm ); + + bool IsVariable() const; + bool IsMethod() const; + + void SetRecordPerItem( bool bSet ) + { + aRecordPerItem = bSet; + if( bSet ) + aRecordPerSet = aNoRecord = false; + } + void SetRecordPerSet( bool bSet ) + { + aRecordPerSet = bSet; + if( bSet ) + aRecordPerItem = aNoRecord = false; + } + void SetNoRecord( bool bSet ) + { + aNoRecord = bSet; + if( bSet ) + aRecordPerItem = aRecordPerSet = false; + } + +public: + SvMetaSlot(); + SvMetaSlot( SvMetaType * pType ); + + const OString& GetGroupId() const; + const OString& GetExecMethod() const; + const OString& GetStateMethod() const; + const OString& GetDisableFlags() const; + bool GetToggle() const; + bool GetAutoUpdate() const; + + bool GetAsynchron() const; + + bool GetRecordPerItem() const; + bool GetRecordPerSet() const; + bool GetNoRecord() const; + bool GetRecordAbsolute() const; + + bool GetMenuConfig() const; + bool GetToolBoxConfig() const; + bool GetAccelConfig() const; + bool GetFastCall() const; + bool GetContainer() const; + bool GetReadOnlyDoc() const; + bool GetExport() const; + bool GetHidden() const; + + sal_uLong GetListPos() const + { return nListPos; } + void SetListPos(sal_uLong n) + { nListPos = n; } + void ResetSlotPointer() + { pNextSlot = nullptr; } + + virtual bool Test( SvTokenStream & rInStm ) override; + virtual void ReadAttributesSvIdl( SvIdlDataBase & rBase, + SvTokenStream & rInStm ) override; + virtual bool ReadSvIdl( SvIdlDataBase &, SvTokenStream & rInStm ) override; + virtual void Insert( SvSlotElementList& ) override; + void WriteSlotStubs( const OString& rShellName, + std::vector & rList, + SvStream & rOutStm ) const; + sal_uInt16 WriteSlotMap( const OString& rShellName, + sal_uInt16 nCount, + SvSlotElementList&, + size_t nStart, + SvIdlDataBase & rBase, + SvStream & rOutStm ); + sal_uInt16 WriteSlotParamArray( SvIdlDataBase & rBase, + SvStream & rOutStm ) const; +}; + +#endif // INCLUDED_IDL_INC_SLOT_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/idl/inc/types.hxx b/idl/inc/types.hxx new file mode 100644 index 000000000..97c353b36 --- /dev/null +++ b/idl/inc/types.hxx @@ -0,0 +1,119 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_IDL_INC_TYPES_HXX +#define INCLUDED_IDL_INC_TYPES_HXX + +#include +#include +#include +#include "basobj.hxx" + +class SvMetaType; +class SvMetaSlot; +typedef SvRefMemberList< SvMetaSlot* > SvSlotElementList; + +class SvMetaAttribute : public SvMetaReference +{ +public: + tools::SvRef aType; + SvIdentifier aSlotId; + SvMetaAttribute(); + SvMetaAttribute( SvMetaType * ); + + void SetSlotId( const SvIdentifier & rId ) + { aSlotId = rId; } + const SvIdentifier& GetSlotId() const; + SvMetaType * GetType() const; + + virtual bool Test( SvTokenStream & rInStm ); + virtual bool ReadSvIdl( SvIdlDataBase &, SvTokenStream & rInStm ) override; + sal_uLong MakeSfx( OStringBuffer& rAtrrArray ) const; + virtual void Insert( SvSlotElementList& ); +}; + +enum MetaTypeType { Method, Struct, Base, Enum, Interface, Shell }; + +class SvMetaType : public SvMetaReference +{ + SvRefMemberList aAttrList; + MetaTypeType nType; + bool bIsItem; + + void WriteSfxItem( const OString& rItemName, SvIdlDataBase const & rBase, + SvStream & rOutStm ); +protected: + bool ReadHeaderSvIdl( SvTokenStream & rInStm ); +public: + SvMetaType(); + SvMetaType( const OString& rTypeName ); + + virtual ~SvMetaType() override; + + virtual void ReadContextSvIdl( SvIdlDataBase &, SvTokenStream & rInStm ) override; + + SvRefMemberList& + GetAttrList() { return aAttrList; } + sal_uLong GetAttrCount() const { return aAttrList.size(); } + + void SetType( MetaTypeType nT ); + MetaTypeType GetMetaTypeType() const { return nType; } + SvMetaType * GetBaseType() const; + SvMetaType * GetReturnType() const; + void SetItem(bool b) { bIsItem = b; } + bool IsItem() const { return bIsItem; } + + virtual bool ReadSvIdl( SvIdlDataBase &, SvTokenStream & rInStm ) override; + + sal_uLong MakeSfx( OStringBuffer& rAtrrArray ); + virtual void WriteSfx( SvIdlDataBase & rBase, SvStream & rOutStm ); + bool ReadMethodArgs( SvIdlDataBase & rBase, + SvTokenStream & rInStm ); +}; + +class SvMetaTypeString final : public SvMetaType +{ +public: + SvMetaTypeString(); +}; + +class SvMetaEnumValue final : public SvMetaObject +{ +public: + SvMetaEnumValue(); +}; + +class SvMetaTypeEnum final : public SvMetaType +{ +public: + SvRefMemberList aEnumValueList; + OString aPrefix; + SvMetaTypeEnum(); +}; + +class SvMetaTypevoid final : public SvMetaType +{ +public: + SvMetaTypevoid(); +}; + + +#endif // INCLUDED_IDL_INC_TYPES_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/idl/source/cmptools/hash.cxx b/idl/source/cmptools/hash.cxx new file mode 100644 index 000000000..ef11b489e --- /dev/null +++ b/idl/source/cmptools/hash.cxx @@ -0,0 +1,70 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +// C and C++ includes +#include + +// program-sensitive includes +#include + +#include + +SvStringHashEntry * SvStringHashTable::Insert( const OString& rElement, sal_uInt32 * pInsertPos ) +{ + auto it = maString2IntMap.find(rElement); + if (it != maString2IntMap.end()) { + *pInsertPos = it->second; + return maInt2EntryMap[*pInsertPos].get(); + } + maString2IntMap[rElement] = mnNextId; + maInt2EntryMap[mnNextId] = std::make_unique(rElement); + *pInsertPos = mnNextId; + mnNextId++; + return maInt2EntryMap[*pInsertPos].get(); +} + +bool SvStringHashTable::Test( const OString& rElement, sal_uInt32 * pInsertPos ) +{ + auto it = maString2IntMap.find(rElement); + if (it != maString2IntMap.end()) { + *pInsertPos = it->second; + return true; + } + return false; +} + +SvStringHashEntry * SvStringHashTable::Get( sal_uInt32 nInsertPos ) const +{ + auto it = maInt2EntryMap.find(nInsertPos); + return it->second.get(); +} + +OString SvStringHashTable::GetNearString( const OString& rName ) const +{ + for( auto const & rPair : maInt2EntryMap ) + { + SvStringHashEntry * pE = rPair.second.get(); + if( pE->GetName().equalsIgnoreAsciiCase( rName ) && pE->GetName() != rName ) + return pE->GetName(); + } + return OString(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/idl/source/cmptools/lex.cxx b/idl/source/cmptools/lex.cxx new file mode 100644 index 000000000..eb9ad1170 --- /dev/null +++ b/idl/source/cmptools/lex.cxx @@ -0,0 +1,336 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include +#include +#include +#include +#include +#include + +OString SvToken::GetTokenAsString() const +{ + OString aStr; + switch( nType ) + { + case SVTOKENTYPE::Empty: + break; + case SVTOKENTYPE::Comment: + aStr = aString; + break; + case SVTOKENTYPE::Integer: + aStr = OString::number(nLong); + break; + case SVTOKENTYPE::String: + aStr = aString; + break; + case SVTOKENTYPE::Bool: + aStr = bBool ? "TRUE" : "FALSE"; + break; + case SVTOKENTYPE::Identifier: + aStr = aString; + break; + case SVTOKENTYPE::Char: + aStr = OString(cChar); + break; + case SVTOKENTYPE::EndOfFile: + case SVTOKENTYPE::HashId: + break; + } + + return aStr; +} + +SvToken & SvToken::operator = ( const SvToken & rObj ) +{ + if( this != &rObj ) + { + nLine = rObj.nLine; + nColumn = rObj.nColumn; + nType = rObj.nType; + aString = rObj.aString; + nLong = rObj.nLong; + } + return *this; +} + +void SvTokenStream::InitCtor() +{ + aStrTrue = OString("TRUE"); + aStrFalse = OString("FALSE"); + nLine = nColumn = 0; + nBufPos = 0; + nMaxPos = 0; + c = GetNextChar(); + FillTokenList(); +} + +SvTokenStream::SvTokenStream( const OUString & rFileName ) + : pInStream( new SvFileStream( rFileName, StreamMode::STD_READ ) ) + , aFileName( rFileName ) +{ + InitCtor(); +} + +SvTokenStream::~SvTokenStream() +{ +} + +void SvTokenStream::FillTokenList() +{ + SvToken * pToken = new SvToken(); + aTokList.push_back(std::unique_ptr(pToken)); + do + { + if( !MakeToken( *pToken ) ) + { + if (!aTokList.empty()) + { + *pToken = SvToken(); + std::vector >::const_iterator it = aTokList.begin(); + + pToken->SetLine((*it)->GetLine()); + pToken->SetColumn((*it)->GetColumn()); + } + break; + } + else if( pToken->IsComment() ) + *pToken = SvToken(); + else if( pToken->IsEof() ) + break; + else + { + pToken = new SvToken(); + aTokList.push_back(std::unique_ptr(pToken)); + } + } + while( !pToken->IsEof() ); + pCurToken = aTokList.begin(); +} + +char SvTokenStream::GetNextChar() +{ + char nChar; + while (aBufStr.getLength() <= nBufPos) + { + if (pInStream->ReadLine(aBufStr)) + { + nLine++; + nColumn = 0; + nBufPos = 0; + } + else + { + aBufStr.clear(); + nColumn = 0; + nBufPos = 0; + return '\0'; + } + } + nChar = aBufStr[nBufPos++]; + nColumn += nChar == '\t' ? nTabSize : 1; + return nChar; +} + +sal_uInt64 SvTokenStream::GetNumber() +{ + sal_uInt64 l = 0; + short nLog = 10; + + if( '0' == c ) + { + c = GetFastNextChar(); + if( 'x' == c ) + { + nLog = 16; + c = GetFastNextChar(); + } + } + + if( nLog == 16 ) + { + while( rtl::isAsciiHexDigit( static_cast(c) ) ) + { + if( rtl::isAsciiDigit( static_cast(c) ) ) + l = l * nLog + (c - '0'); + else + l = l * nLog + + (rtl::toAsciiUpperCase( static_cast(c) ) + - 'A' + 10 ); + c = GetFastNextChar(); + } + } + else + { + while( rtl::isAsciiDigit( static_cast(c) ) || 'x' == c ) + { + l = l * nLog + (c - '0'); + c = GetFastNextChar(); + } + } + + return l; +} + +bool SvTokenStream::MakeToken( SvToken & rToken ) +{ + do + { + if( 0 == c ) + c = GetNextChar(); + // skip whitespace + while( rtl::isAsciiWhiteSpace( static_cast(c) ) + || 26 == c ) + { + c = GetFastNextChar(); + nColumn += c == '\t' ? nTabSize : 1; + } + } + while( 0 == c && !IsEof() && ( ERRCODE_NONE == pInStream->GetError() ) ); + + sal_uInt64 nLastLine = nLine; + sal_uInt64 nLastColumn = nColumn; + // comment + if( '/' == c ) + { + // time optimization, no comments + char c1 = c; + c = GetFastNextChar(); + if( '/' == c ) + { + while( '\0' != c ) + { + c = GetFastNextChar(); + } + c = GetNextChar(); + rToken.nType = SVTOKENTYPE::Comment; + } + else if( '*' == c ) + { + c = GetFastNextChar(); + do + { + while( '*' != c ) + { + if( '\0' == c ) + { + c = GetNextChar(); + if( IsEof() ) + return false; + } + else + c = GetFastNextChar(); + } + c = GetFastNextChar(); + } + while( '/' != c && !IsEof() && ( ERRCODE_NONE == pInStream->GetError() ) ); + if( IsEof() || ( ERRCODE_NONE != pInStream->GetError() ) ) + return false; + c = GetNextChar(); + rToken.nType = SVTOKENTYPE::Comment; + CalcColumn(); + } + else + { + rToken.nType = SVTOKENTYPE::Char; + rToken.cChar = c1; + } + } + else if( c == '"' ) + { + OStringBuffer aStr(128); + bool bDone = false; + while( !bDone && !IsEof() && c ) + { + c = GetFastNextChar(); + if( '\0' == c ) + { + // read strings beyond end of line + aStr.append('\n'); + c = GetNextChar(); + if( IsEof() ) + return false; + } + if( c == '"' ) + { + c = GetFastNextChar(); + bDone = true; + } + else + aStr.append(c); + } + if( IsEof() || ( ERRCODE_NONE != pInStream->GetError() ) ) + return false; + rToken.nType = SVTOKENTYPE::String; + rToken.aString = aStr.makeStringAndClear(); + } + else if( rtl::isAsciiDigit( static_cast(c) ) ) + { + rToken.nType = SVTOKENTYPE::Integer; + rToken.nLong = GetNumber(); + + } + else if( rtl::isAsciiAlpha (static_cast(c)) || (c == '_') ) + { + OStringBuffer aBuf(64); + while( rtl::isAsciiAlphanumeric( static_cast(c) ) + || c == '_' || c == ':') + { + aBuf.append(c); + c = GetFastNextChar(); + } + OString aStr = aBuf.makeStringAndClear(); + if( aStr.equalsIgnoreAsciiCase( aStrTrue ) ) + { + rToken.nType = SVTOKENTYPE::Bool; + rToken.bBool = true; + } + else if( aStr.equalsIgnoreAsciiCase( aStrFalse ) ) + { + rToken.nType = SVTOKENTYPE::Bool; + rToken.bBool = false; + } + else + { + sal_uInt32 nHashId; + if( GetIdlApp().pHashTable->Test( aStr, &nHashId ) ) + rToken.SetHash( GetIdlApp().pHashTable->Get( nHashId ) ); + else + { + rToken.nType = SVTOKENTYPE::Identifier; + rToken.aString = aStr; + } + } + } + else if( IsEof() ) + { + rToken.nType = SVTOKENTYPE::EndOfFile; + } + else + { + rToken.nType = SVTOKENTYPE::Char; + rToken.cChar = c; + c = GetFastNextChar(); + } + rToken.SetLine( nLastLine ); + rToken.SetColumn( nLastColumn ); + return pInStream->GetError() == ERRCODE_NONE; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/idl/source/objects/basobj.cxx b/idl/source/objects/basobj.cxx new file mode 100644 index 000000000..6ec830a6f --- /dev/null +++ b/idl/source/objects/basobj.cxx @@ -0,0 +1,143 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include + +#include + +#include +#include +#include +#include + +void SvMetaObject::WriteTab( SvStream & rOutStm, sal_uInt16 nTab ) +{ + while( nTab-- ) + rOutStm.WriteCharPtr( " " ); +} + +void SvMetaObject::WriteStars( SvStream & rOutStm ) +{ + rOutStm.WriteChar( '/' ); + for( int i = 6; i > 0; i-- ) + rOutStm.WriteCharPtr( "**********" ); + rOutStm.WriteChar( '/' ) << endl; +} + +void SvMetaObject::Back2Delimiter( SvStream & rOutStm ) +{ + // write no empty brackets + sal_uLong nPos = rOutStm.Tell(); + rOutStm.SeekRel( -1 ); + char c = 0; + rOutStm.ReadChar( c ); + + while( rtl::isAsciiWhiteSpace( static_cast(c) ) + && rOutStm.Tell() != 1 ) + { + rOutStm.SeekRel( -2 ); + rOutStm.ReadChar( c ); + } + + if( c == ';' || c == ',' ) + rOutStm.SeekRel( -1 ); + else + rOutStm.Seek( nPos ); +} + +SvMetaObject::SvMetaObject() +{ +} + +void SvMetaObject::SetName( const OString& rName ) +{ + aName = rName; +} + +bool SvMetaObject::ReadNameSvIdl( SvTokenStream & rInStm ) +{ + sal_uInt32 nTokPos = rInStm.Tell(); + SvToken& rTok = rInStm.GetToken_Next(); + + // read module name + if( rTok.IsIdentifier() ) + { + SetName( rTok.GetString() ); + return true; + } + + rInStm.Seek( nTokPos ); + return false; +} + +void SvMetaObject::ReadAttributesSvIdl( SvIdlDataBase & , + SvTokenStream & ) +{ +} + +void SvMetaObject::DoReadContextSvIdl( SvIdlDataBase & rBase, + SvTokenStream & rInStm ) +{ + sal_uInt32 nBeginPos = 0; // can not happen with Tell + while( nBeginPos != rInStm.Tell() ) + { + nBeginPos = rInStm.Tell(); + ReadContextSvIdl( rBase, rInStm ); + rInStm.ReadIfDelimiter(); + } +} + +void SvMetaObject::ReadContextSvIdl( SvIdlDataBase &, SvTokenStream & ) +{ +} + +bool SvMetaObject::ReadSvIdl( SvIdlDataBase & rBase, SvTokenStream & rInStm ) +{ + sal_uInt32 nTokPos = rInStm.Tell(); + bool bOk = true; + if( rInStm.ReadIf( '[' ) ) + { + sal_uInt32 nBeginPos = 0; // can not happen with Tell + while( nBeginPos != rInStm.Tell() ) + { + nBeginPos = rInStm.Tell(); + ReadAttributesSvIdl( rBase, rInStm ); + rInStm.ReadIfDelimiter(); + } + bOk = rInStm.ReadIf( ']' ); + } + + if( bOk && rInStm.ReadIf( '{' ) ) + { + DoReadContextSvIdl( rBase, rInStm ); + bOk = rInStm.ReadIf( '}' ); + } + + if( !bOk ) + rInStm.Seek( nTokPos ); + return bOk; +} + + +SvMetaReference::SvMetaReference() +{ +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/idl/source/objects/bastype.cxx b/idl/source/objects/bastype.cxx new file mode 100644 index 000000000..0dddd98d5 --- /dev/null +++ b/idl/source/objects/bastype.cxx @@ -0,0 +1,123 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include +#include +#include +#include +#include +#include +#include + +bool SvBOOL::ReadSvIdl( SvStringHashEntry const * pName, SvTokenStream & rInStm ) +{ + sal_uInt32 nTokPos = rInStm.Tell(); + SvToken& rTok = rInStm.GetToken_Next(); + + if( rTok.Is( pName ) ) + { + if( rInStm.ReadIf( '=' ) ) + { + rTok = rInStm.GetToken(); + if( !rTok.IsBool() ) + throw SvParseException(rInStm, "xxx"); + *this = rTok.GetBool(); + rInStm.GetToken_Next(); + } + else + *this = true; //default action set to TRUE + return true; + } + rInStm.Seek( nTokPos ); + return false; +} + +void SvIdentifier::ReadSvIdl( SvStringHashEntry const * pName, SvTokenStream & rInStm ) +{ + sal_uInt32 nTokPos = rInStm.Tell(); + SvToken& rTok = rInStm.GetToken_Next(); + + if( rTok.Is( pName ) ) + { + bool bOk = true; + bool bBracket = rInStm.ReadIf( '(' ); + if( bBracket || rInStm.ReadIf( '=' ) ) + { + rTok = rInStm.GetToken(); + if( rTok.IsIdentifier() ) + { + setString(rTok.GetString()); + rInStm.GetToken_Next(); + } + if( bOk && bBracket ) + bOk = rInStm.ReadIf( ')' ); + } + if( bOk ) + return; + } + rInStm.Seek( nTokPos ); +} + +void SvIdentifier::ReadSvIdl( SvIdlDataBase & rBase, + SvTokenStream & rInStm ) +{ + sal_uInt32 nTokPos = rInStm.Tell(); + SvToken& rTok = rInStm.GetToken_Next(); + + if( rTok.IsIdentifier() ) + { + sal_uLong n; + if( !rBase.FindId( rTok.GetString(), &n ) ) + rBase.SetAndWriteError( rInStm, "no value for identifier <" + getString() + "> " ); + setString(rTok.GetString()); + nValue = n; + return; + } + rInStm.Seek( nTokPos ); +} + +bool ReadStringSvIdl( SvStringHashEntry const * pName, SvTokenStream & rInStm, OString& aRetString ) +{ + sal_uInt32 nTokPos = rInStm.Tell(); + SvToken& rTok = rInStm.GetToken_Next(); + + if( rTok.Is( pName ) ) + { + bool bOk = true; + bool bBracket = rInStm.ReadIf( '(' ); + if( bBracket || rInStm.ReadIf( '=' ) ) + { + rTok = rInStm.GetToken(); + if( rTok.IsString() ) + { + aRetString = rTok.GetString(); + rInStm.GetToken_Next(); + } + if( bOk && bBracket ) + bOk = rInStm.ReadIf( ')' ); + } + if( bOk ) + return true; + } + rInStm.Seek( nTokPos ); + return false; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/idl/source/objects/module.cxx b/idl/source/objects/module.cxx new file mode 100644 index 000000000..fe64287ae --- /dev/null +++ b/idl/source/objects/module.cxx @@ -0,0 +1,39 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include +#include +#include +#include + + +SvMetaModule::SvMetaModule() +{ +} + +void SvMetaModule::WriteSfx( SvIdlDataBase & rBase, SvStream & rOutStm ) +{ + for( sal_uLong n = 0; n < aClassList.size(); n++ ) + { + SvMetaClass * pClass = aClassList[n]; + pClass->WriteSfx( rBase, rOutStm ); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/idl/source/objects/object.cxx b/idl/source/objects/object.cxx new file mode 100644 index 000000000..a424bb748 --- /dev/null +++ b/idl/source/objects/object.cxx @@ -0,0 +1,347 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include + +#include + +#include +#include +#include + +#include +#include +#include + + +SvClassElement::SvClassElement() +{ +}; + +SvMetaClass::SvMetaClass() +{ +} + +void SvMetaClass::ReadContextSvIdl( SvIdlDataBase & rBase, + SvTokenStream & rInStm ) +{ + sal_uInt32 nTokPos = rInStm.Tell(); + SvToken& rTok = rInStm.GetToken_Next(); + + if( rTok.Is( SvHash_import() ) ) + { + SvMetaClass * pClass = rBase.ReadKnownClass( rInStm ); + if( !pClass ) + throw SvParseException( rInStm, "unknown imported interface" ); + SvClassElement aEle; + aEle.SetClass( pClass ); + aClassElementList.push_back( aEle ); + + rTok = rInStm.GetToken(); + if( rTok.IsString() ) + { + aEle.SetPrefix( rTok.GetString() ); + rInStm.GetToken_Next(); + } + return; + } + else + { + rInStm.Seek( nTokPos ); + SvMetaType * pType = rBase.ReadKnownType( rInStm ); + + bool bOk = false; + tools::SvRef xAttr; + if( !pType || pType->IsItem() ) + { + xAttr = new SvMetaSlot( pType ); + if( xAttr->ReadSvIdl( rBase, rInStm ) ) + bOk = xAttr->Test( rInStm ); + } + else + { + xAttr = new SvMetaAttribute( pType ); + if( xAttr->ReadSvIdl( rBase, rInStm ) ) + bOk = xAttr->Test( rInStm ); + } + + if( bOk ) + bOk = TestAttribute( rBase, rInStm, *xAttr ); + if( bOk ) + { + if( !xAttr->GetSlotId().IsSet() ) + { + SvIdentifier aI; + aI.SetValue( rBase.GetUniqueId() ); + xAttr->SetSlotId( aI ); + } + aAttrList.push_back( xAttr.get() ); + return; + } + } + rInStm.Seek( nTokPos ); +} + +bool SvMetaClass::TestAttribute( SvIdlDataBase & rBase, SvTokenStream & rInStm, + SvMetaAttribute & rAttr ) const +{ + if ( !rAttr.GetRef() && dynamic_cast(&rAttr) ) + { + SAL_WARN( "idl", "new slot : " << rAttr.GetSlotId().getString() ); + } + + for( sal_uLong n = 0; n < aAttrList.size(); n++ ) + { + SvMetaAttribute * pS = aAttrList[n]; + if( pS->GetName() == rAttr.GetName() ) + { + // values have to match + if( pS->GetSlotId().GetValue() != rAttr.GetSlotId().GetValue() ) + { + throw SvParseException( rInStm, "Attribute's " + pS->GetName() + " with different id's"); + } + } + else + { + sal_uInt32 nId1 = pS->GetSlotId().GetValue(); + sal_uInt32 nId2 = rAttr.GetSlotId().GetValue(); + if( nId1 == nId2 && nId1 != 0 ) + { + OString aStr = "Attribute " + pS->GetName() + " and Attribute " + rAttr.GetName() + " with equal id's"; + throw SvParseException(rInStm, aStr); + } + } + } + SvMetaClass * pSC = aSuperClass.get(); + if( pSC ) + return pSC->TestAttribute( rBase, rInStm, rAttr ); + return true; +} + +sal_uInt16 SvMetaClass::WriteSlotParamArray( SvIdlDataBase & rBase, + SvSlotElementList & rSlotList, + SvStream & rOutStm ) +{ + sal_uInt16 nCount = 0; + for ( size_t i = 0, n = rSlotList.size(); i < n; ++i ) + { + SvMetaSlot *pAttr = rSlotList[ i ]; + nCount = nCount + pAttr->WriteSlotParamArray( rBase, rOutStm ); + } + + return nCount; +} + +sal_uInt16 SvMetaClass::WriteSlots( const OString& rShellName, + SvSlotElementList & rSlotList, + SvIdlDataBase & rBase, + SvStream & rOutStm ) +{ + sal_uInt16 nSCount = 0; + for ( size_t i = 0, n = rSlotList.size(); i < n; ++i ) + { + SvMetaSlot * pAttr = rSlotList[ i ]; + nSCount = nSCount + pAttr->WriteSlotMap( rShellName, nSCount, + rSlotList, i, rBase, + rOutStm ); + } + + return nSCount; +} + +void SvMetaClass::InsertSlots( SvSlotElementList& rList, std::vector& rSuperList, + SvMetaClassList &rClassList, + const OString& rPrefix, SvIdlDataBase& rBase) +{ + // was this class already written? + for ( size_t i = 0, n = rClassList.size(); i < n ; ++i ) + if ( rClassList[ i ] == this ) + return; + + rClassList.push_back( this ); + + // write all direct attributes + sal_uLong n; + for( n = 0; n < aAttrList.size(); n++ ) + { + SvMetaAttribute * pAttr = aAttrList[n]; + + sal_uLong nId = pAttr->GetSlotId().GetValue(); + + std::vector::iterator iter = std::find(rSuperList.begin(), + rSuperList.end(),nId); + + if( iter == rSuperList.end() ) + { + // Write only if not already written by subclass or + // imported interface. + rSuperList.push_back(nId); + pAttr->Insert(rList); + } + } + + // All Interfaces already imported by SuperShell should not be + // written any more. + // It is prohibited that Shell and SuperShell directly import the same + // class. + if( GetMetaTypeType() == MetaTypeType::Shell && aSuperClass.is() ) + aSuperClass->FillClasses( rClassList ); + + // Write all attributes of the imported classes, as long as they have + // not already been imported by the superclass. + for( n = 0; n < aClassElementList.size(); n++ ) + { + SvClassElement& rElement = aClassElementList[n]; + SvMetaClass * pCl = rElement.GetClass(); + OStringBuffer rPre(rPrefix.getLength() + 1 + rElement.GetPrefix().getLength()); + rPre.append(rPrefix); + if( !rPre.isEmpty() && !rElement.GetPrefix().isEmpty() ) + rPre.append('.'); + rPre.append(rElement.GetPrefix()); + + // first of all write direct imported interfaces + pCl->InsertSlots( rList, rSuperList, rClassList, + rPre.makeStringAndClear(), rBase ); + } + + // only write superclass if no shell and not in the list + if( GetMetaTypeType() != MetaTypeType::Shell && aSuperClass.is() ) + { + aSuperClass->InsertSlots( rList, rSuperList, rClassList, rPrefix, rBase ); + } +} + +void SvMetaClass::FillClasses( SvMetaClassList & rList ) +{ + // Am I not yet in? + for ( size_t i = 0, n = rList.size(); i < n; ++i ) + if ( rList[ i ] == this ) + return; + + rList.push_back( this ); + + // my imports + for( size_t n = 0; n < aClassElementList.size(); n++ ) + { + SvClassElement& rElement = aClassElementList[n]; + SvMetaClass * pCl = rElement.GetClass(); + pCl->FillClasses( rList ); + } + + // my superclass + if( aSuperClass.is() ) + aSuperClass->FillClasses( rList ); +} + + +void SvMetaClass::WriteSlotStubs( const OString& rShellName, + SvSlotElementList & rSlotList, + std::vector & rList, + SvStream & rOutStm ) +{ + // write all attributes + for ( size_t i = 0, n = rSlotList.size(); i < n; ++i ) + { + SvMetaSlot *pAttr = rSlotList[ i ]; + pAttr->WriteSlotStubs( rShellName, rList, rOutStm ); + } +} + +void SvMetaClass::WriteSfx( SvIdlDataBase & rBase, SvStream & rOutStm ) +{ + WriteStars( rOutStm ); + // define class + rOutStm.WriteCharPtr( "#ifdef ShellClass_" ).WriteOString( GetName() ) << endl; + rOutStm.WriteCharPtr( "#undef ShellClass" ) << endl; + rOutStm.WriteCharPtr( "#undef ShellClass_" ).WriteOString( GetName() ) << endl; + rOutStm.WriteCharPtr( "#define ShellClass " ).WriteOString( GetName() ) << endl; + + // no slotmaps get written for interfaces + if( GetMetaTypeType() != MetaTypeType::Shell ) + { + rOutStm.WriteCharPtr( "#endif" ) << endl << endl; + return; + } + // write parameter array + rOutStm.WriteCharPtr("static SfxFormalArgument a").WriteOString(GetName()).WriteCharPtr("Args_Impl[] =") << endl; + rOutStm.WriteChar('{') << endl; + + std::vector aSuperList; + SvMetaClassList classList; + SvSlotElementList aSlotList; + InsertSlots(aSlotList, aSuperList, classList, OString(), rBase); + for ( size_t i = 0, n = aSlotList.size(); i < n; ++i ) + { + SvMetaSlot *pSlot = aSlotList[ i ]; + pSlot->SetListPos( i ); + } + + size_t nSlotCount = aSlotList.size(); + + // write all attributes + sal_uInt16 nArgCount = WriteSlotParamArray( rBase, aSlotList, rOutStm ); + if( nArgCount ) + Back2Delimiter( rOutStm ); + else + { + // at least one dummy + WriteTab( rOutStm, 1 ); + rOutStm.WriteCharPtr("{ (const SfxType*) &aSfxVoidItem_Impl, 0, 0 }" ) << endl; + } + rOutStm << endl; + rOutStm.WriteCharPtr( "};" ) << endl << endl; + + std::vector aStringList; + WriteSlotStubs( GetName(), aSlotList, aStringList, rOutStm ); + aStringList.clear(); + + rOutStm << endl; + + // write slotmap + rOutStm.WriteCharPtr("static SfxSlot a").WriteOString(GetName()).WriteCharPtr("Slots_Impl[] =") << endl; + rOutStm.WriteChar( '{' ) << endl; + + // write all attributes + WriteSlots( GetName(), aSlotList, rBase, rOutStm ); + if( nSlotCount ) + Back2Delimiter( rOutStm ); + else + { + // at least one dummy + WriteTab( rOutStm, 1 ); + rOutStm.WriteCharPtr( "SFX_SLOT_ARG(" ).WriteOString( GetName() ) + .WriteCharPtr( ", 0, SfxGroupId::NONE, " ) + .WriteCharPtr( "SFX_STUB_PTR_EXEC_NONE," ) + .WriteCharPtr( "SFX_STUB_PTR_STATE_NONE," ) + .WriteCharPtr( "SfxSlotMode::NONE, SfxVoidItem, 0, 0, \"\", SfxSlotMode::NONE )" ) << endl; + } + rOutStm << endl; + rOutStm.WriteCharPtr( "};" ) << endl; + rOutStm.WriteCharPtr( "#endif" ) << endl << endl; + + for( size_t i = 0, n = aSlotList.size(); i < n; ++i ) + { + SvMetaSlot* pAttr = aSlotList[ i ]; + pAttr->ResetSlotPointer(); + } + + aSlotList.clear(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/idl/source/objects/slot.cxx b/idl/source/objects/slot.cxx new file mode 100644 index 000000000..1793da697 --- /dev/null +++ b/idl/source/objects/slot.cxx @@ -0,0 +1,651 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include +#include +#include +#include +#include +#include + + +SvMetaSlot::SvMetaSlot() + : aRecordPerSet( true ) + , aRecordAbsolute( false ) + , pNextSlot(nullptr) + , nListPos(0) + , aReadOnlyDoc ( true ) + , aExport( true ) +{ +} + +SvMetaSlot::SvMetaSlot( SvMetaType * pType ) + : SvMetaAttribute( pType ) + , aRecordPerSet( true ) + , aRecordAbsolute( false ) + , pNextSlot(nullptr) + , nListPos(0) + , aReadOnlyDoc ( true ) + , aExport( true ) +{ +} + +bool SvMetaSlot::GetReadOnlyDoc() const +{ + if( aReadOnlyDoc.IsSet() || !GetRef() ) return aReadOnlyDoc; + return static_cast(GetRef())->GetReadOnlyDoc(); +} + +bool SvMetaSlot::GetExport() const +{ + if( aExport.IsSet() || !GetRef() ) return aExport; + return static_cast(GetRef())->GetExport(); +} + +bool SvMetaSlot::GetHidden() const +{ + // when export is set, but hidden is not the default is used + if ( aExport.IsSet() ) + return !aExport; + else if( !GetRef() ) + return false; + else + return static_cast(GetRef())->GetHidden(); +} + +bool SvMetaSlot::IsVariable() const +{ + SvMetaType * pType = GetType(); + return pType->GetMetaTypeType() != MetaTypeType::Method; +} + +bool SvMetaSlot::IsMethod() const +{ + SvMetaType * pType = GetType(); + return pType->GetMetaTypeType() == MetaTypeType::Method; +} + +/************************************************************************* +|* reference +|* +|* description Second FALSE in the SvBOOL-Objects means +|* IsSet() provides FALSE (default initialization). +*************************************************************************/ +/** reference disbandment **/ +const OString& SvMetaSlot::GetGroupId() const +{ + if( !aGroupId.getString().isEmpty() || !GetRef() ) return aGroupId.getString(); + return static_cast(GetRef())->GetGroupId(); +} +const OString& SvMetaSlot::GetDisableFlags() const +{ + if( !aDisableFlags.isEmpty() || !GetRef() ) return aDisableFlags; + return static_cast(GetRef())->GetDisableFlags(); +} +const OString& SvMetaSlot::GetExecMethod() const +{ + if( !aExecMethod.getString().isEmpty() || !GetRef() ) return aExecMethod.getString(); + return static_cast(GetRef())->GetExecMethod(); +} +const OString& SvMetaSlot::GetStateMethod() const +{ + if( !aStateMethod.getString().isEmpty() || !GetRef() ) return aStateMethod.getString(); + return static_cast(GetRef())->GetStateMethod(); +} +bool SvMetaSlot::GetToggle() const +{ + if( aToggle.IsSet() || !GetRef() ) return aToggle; + return static_cast(GetRef())->GetToggle(); +} +bool SvMetaSlot::GetAutoUpdate() const +{ + if( aAutoUpdate.IsSet() || !GetRef() ) return aAutoUpdate; + return static_cast(GetRef())->GetAutoUpdate(); +} +bool SvMetaSlot::GetAsynchron() const +{ + // Synchron and Asynchron are exclusive + if( !GetRef() || aAsynchron.IsSet() ) + return aAsynchron; + return static_cast(GetRef())->GetAsynchron(); +} +bool SvMetaSlot::GetRecordPerItem() const +{ + // Record- PerItem, No, PerSet and Manual are exclusive + if( !GetRef() || aRecordPerItem.IsSet() || aNoRecord.IsSet() + || aRecordPerSet.IsSet() ) + return aRecordPerItem; + return static_cast(GetRef())->GetRecordPerItem(); +} +bool SvMetaSlot::GetRecordPerSet() const +{ + // Record- PerItem, No, PerSet and Manual are exclusive + if( !GetRef() || aRecordPerItem.IsSet() || aNoRecord.IsSet() + || aRecordPerSet.IsSet() ) + return aRecordPerSet; + return static_cast(GetRef())->GetRecordPerSet(); +} +bool SvMetaSlot::GetNoRecord() const +{ + // Record- PerItem, No, PerSet and Manual are exclusive + if( !GetRef() || aRecordPerItem.IsSet() || aNoRecord.IsSet() + || aRecordPerSet.IsSet() ) + return aNoRecord; + return static_cast(GetRef())->GetNoRecord(); +} +bool SvMetaSlot::GetRecordAbsolute() const +{ + if( !GetRef() || aRecordAbsolute.IsSet() ) + return aRecordAbsolute; + return static_cast(GetRef())->GetRecordAbsolute(); +} +bool SvMetaSlot::GetMenuConfig() const +{ + if( aMenuConfig.IsSet() || !GetRef() ) return aMenuConfig; + return static_cast(GetRef())->GetMenuConfig(); +} +bool SvMetaSlot::GetToolBoxConfig() const +{ + if( aToolBoxConfig.IsSet() || !GetRef() ) return aToolBoxConfig; + return static_cast(GetRef())->GetToolBoxConfig(); +} +bool SvMetaSlot::GetAccelConfig() const +{ + if( aAccelConfig.IsSet() || !GetRef() ) return aAccelConfig; + return static_cast(GetRef())->GetAccelConfig(); +} +bool SvMetaSlot::GetFastCall() const +{ + if( aFastCall.IsSet() || !GetRef() ) return aFastCall; + return static_cast(GetRef())->GetFastCall(); +} +bool SvMetaSlot::GetContainer() const +{ + if( aContainer.IsSet() || !GetRef() ) return aContainer; + return static_cast(GetRef())->GetContainer(); +} + +void SvMetaSlot::ReadAttributesSvIdl( SvIdlDataBase & rBase, + SvTokenStream & rInStm ) +{ + SvMetaAttribute::ReadAttributesSvIdl( rBase, rInStm ); + + aGroupId.ReadSvIdl( SvHash_GroupId(), rInStm ); + aExecMethod.ReadSvIdl( SvHash_ExecMethod(), rInStm ); + aStateMethod.ReadSvIdl( SvHash_StateMethod(), rInStm ); + ReadStringSvIdl( SvHash_DisableFlags(), rInStm, aDisableFlags ); + aReadOnlyDoc.ReadSvIdl( SvHash_ReadOnlyDoc(), rInStm ); + aExport.ReadSvIdl( SvHash_Export(), rInStm ); + aToggle.ReadSvIdl( SvHash_Toggle(), rInStm ); + aAutoUpdate.ReadSvIdl( SvHash_AutoUpdate(), rInStm ); + aAsynchron.ReadSvIdl( SvHash_Asynchron(), rInStm ); + aRecordAbsolute.ReadSvIdl( SvHash_RecordAbsolute(), rInStm ); + + if( aRecordPerItem.ReadSvIdl( SvHash_RecordPerItem(), rInStm ) ) + { + SetRecordPerItem( aRecordPerItem ); + } + if( aRecordPerSet.ReadSvIdl( SvHash_RecordPerSet(), rInStm ) ) + { + SetRecordPerSet( aRecordPerSet ); + } + if( aNoRecord.ReadSvIdl( SvHash_NoRecord(), rInStm ) ) + { + SetNoRecord( aNoRecord ); + } + + aMenuConfig.ReadSvIdl( SvHash_MenuConfig(), rInStm ); + aToolBoxConfig.ReadSvIdl( SvHash_ToolBoxConfig(), rInStm ); + aAccelConfig.ReadSvIdl( SvHash_AccelConfig(), rInStm ); + + aFastCall.ReadSvIdl( SvHash_FastCall(), rInStm ); + aContainer.ReadSvIdl( SvHash_Container(), rInStm ); +} + +bool SvMetaSlot::Test( SvTokenStream & rInStm ) +{ + bool bOk = SvMetaAttribute::Test( rInStm ); + if( bOk ) + { + SvMetaType * pType = GetType(); + if( pType->GetMetaTypeType() == MetaTypeType::Method ) + pType = pType->GetReturnType(); + if( !pType->IsItem() ) + { + throw SvParseException( rInStm, "this attribute is not a slot" ); + } + } + + return bOk; +} + +bool SvMetaSlot::ReadSvIdl( SvIdlDataBase & rBase, SvTokenStream & rInStm ) +{ + sal_uInt32 nTokPos = rInStm.Tell(); + bool bOk = true; + + SvMetaAttribute * pAttr = rBase.ReadKnownAttr( rInStm, GetType() ); + if( pAttr ) + { + // c + SvMetaSlot * pKnownSlot = dynamic_cast( pAttr ); + if( !pKnownSlot ) + throw SvParseException( rInStm, "attribute " + pAttr->GetName() + " is method or variable but not a slot" ); + SetRef( pKnownSlot ); + SetName( pKnownSlot->GetName() ); + bOk = SvMetaObject::ReadSvIdl( rBase, rInStm ); + } + else + { + bOk = SvMetaAttribute::ReadSvIdl( rBase, rInStm ); + + SvMetaAttribute *pAttr2 = rBase.FindKnownAttr( GetSlotId() ); + if( pAttr2 ) + { + // for testing purposes: reference in case of complete definition + SvMetaSlot * pKnownSlot = dynamic_cast( pAttr2 ); + if( !pKnownSlot ) + throw SvParseException( rInStm, "attribute " + pAttr2->GetName() + " is method or variable but not a slot" ); + SetRef( pKnownSlot ); + + // names may differ, because explicitly given + if ( pKnownSlot->GetName() != GetName() ) + { + OSL_FAIL("Illegal definition!"); + rInStm.Seek( nTokPos ); + return false; + } + + SetName( pKnownSlot->GetName() ); + } + } + + if( !bOk ) + rInStm.Seek( nTokPos ); + + return bOk; +} + +void SvMetaSlot::Insert( SvSlotElementList& rList) +{ + // get insert position through binary search in slotlist + sal_uInt16 nId = static_cast(GetSlotId().GetValue()); + sal_uInt16 nListCount = static_cast(rList.size()); + sal_uInt16 nPos; + + if ( !nListCount ) + nPos = 0; + else if ( nListCount == 1 ) + nPos = rList[ 0 ]->GetSlotId().GetValue() >= nId ? 0 : 1; + else + { + sal_uInt16 nMid = 0, nLow = 0; + sal_uInt16 nHigh = nListCount - 1; + bool bFound = false; + while ( !bFound && nLow <= nHigh ) + { + nMid = (nLow + nHigh) >> 1; + DBG_ASSERT( nMid < nListCount, "bsearch is buggy" ); + int nDiff = static_cast(nId) - static_cast(rList[ nMid ]->GetSlotId().GetValue()); + if ( nDiff < 0) + { + if ( nMid == 0 ) + break; + nHigh = nMid - 1; + } + else if ( nDiff > 0 ) + { + nLow = nMid + 1; + if ( nLow == 0 ) + break; + } + else + bFound = true; + } + + DBG_ASSERT(!bFound, "Duplicate SlotId!"); + nPos = bFound ? nMid : nLow; + } + + DBG_ASSERT( nPos <= nListCount, + "nPos too large" ); + DBG_ASSERT( nPos == nListCount || nId <= + static_cast(rList[ nPos ]->GetSlotId().GetValue()), + "Successor has lower SlotId" ); + DBG_ASSERT( nPos == 0 || nId > + static_cast(rList[ nPos-1 ]->GetSlotId().GetValue()), + "Predecessor has higher SlotId" ); + DBG_ASSERT( nPos+1 >= nListCount || nId < + static_cast(rList[ nPos+1 ]->GetSlotId().GetValue()), + "Successor has lower SlotId" ); + + if ( nPos < rList.size() ) + { + SvSlotElementList::iterator it = rList.begin(); + std::advance( it, nPos ); + rList.insert( it, this ); + } + else + { + rList.push_back( this ); + } +} + + +static OString MakeSlotName( SvStringHashEntry const * pEntry ) +{ + return "SfxSlotMode::" + pEntry->GetName().toAsciiUpperCase(); +}; + +void SvMetaSlot::WriteSlotStubs( const OString& rShellName, + std::vector & rList, + SvStream & rOutStm ) const +{ + if ( !GetExport() && !GetHidden() ) + return; + + OString aMethodName( GetExecMethod() ); + if ( !aMethodName.isEmpty() && + aMethodName != "NoExec" ) + { + bool bIn = false; + for( size_t n = 0; n < rList.size(); n++ ) + { + if (rList[n] == aMethodName) + { + bIn = true; + break; + } + } + + if ( !bIn ) + { + rList.push_back( aMethodName ); + rOutStm.WriteCharPtr( "SFX_EXEC_STUB(" ) + .WriteOString( rShellName ) + .WriteChar( ',' ) + .WriteOString( aMethodName ) + .WriteChar( ')' ) << endl; + } + } + + aMethodName = GetStateMethod(); + if (aMethodName.isEmpty() || aMethodName == "NoState") + return; + + bool bIn = false; + for ( size_t n=0; n < rList.size(); n++ ) + { + if (rList[n] == aMethodName) + { + bIn = true; + break; + } + } + + if ( !bIn ) + { + rList.push_back( aMethodName ); + rOutStm.WriteCharPtr( "SFX_STATE_STUB(" ) + .WriteOString( rShellName ) + .WriteChar( ',' ) + .WriteOString( aMethodName ) + .WriteChar( ')' ) << endl; + } +} + +void SvMetaSlot::WriteSlot( const OString& rShellName, sal_uInt16 nCount, + const OString& rSlotId, + SvSlotElementList& rSlotList, + size_t nStart, + SvIdlDataBase & rBase, SvStream & rOutStm ) +{ + if ( !GetExport() && !GetHidden() ) + return; + + rOutStm.WriteCharPtr( "// Slot Nr. " ) + .WriteOString( OString::number(nListPos) ) + .WriteCharPtr( " : " ); + OString aSlotIdValue(OString::number(GetSlotId().GetValue())); + rOutStm.WriteOString( aSlotIdValue ) << endl; + WriteTab( rOutStm, 1 ); + rOutStm.WriteCharPtr( "SFX_NEW_SLOT_ARG( " ).WriteOString( rShellName ).WriteChar( ',' ) ; + + rOutStm.WriteOString( rSlotId ).WriteChar( ',' ); + + // GroupId + if( !GetGroupId().isEmpty() ) + rOutStm.WriteOString( GetGroupId() ); + else + rOutStm.WriteCharPtr( "SfxGroupId::NONE" ); + rOutStm.WriteChar( ',' ) << endl; + WriteTab( rOutStm, 4 ); + + // look for the next slot with the same StateMethod like me + // the slotlist is set to the current slot + size_t i = nStart; + SvMetaSlot* pEle = ( ++i < rSlotList.size() ) ? rSlotList[ i ] : nullptr; + pNextSlot = pEle; + while ( pNextSlot ) + { + if ( !pNextSlot->pNextSlot && + pNextSlot->GetStateMethod() == GetStateMethod() + ) { + break; + } + pEle = ( ++i < rSlotList.size() ) ? rSlotList[ i ] : nullptr; + pNextSlot = pEle; + } + + if ( !pNextSlot ) + { + // There is no slot behind me that has the same ExecMethod. + // So I search for the first slot with it (could be myself). + i = 0; + pEle = rSlotList.empty() ? nullptr : rSlotList[ i ]; + pNextSlot = pEle; + while (pNextSlot && pNextSlot != this) + { + if ( pNextSlot->GetStateMethod() == GetStateMethod() ) + break; + pEle = ( ++i < rSlotList.size() ) ? rSlotList[ i ] : nullptr; + pNextSlot = pEle; + } + } + + assert(pNextSlot); + + rOutStm.WriteCharPtr( "&a" ).WriteOString( rShellName ).WriteCharPtr( "Slots_Impl[" ) + .WriteOString( OString::number(pNextSlot->GetListPos()) ) + .WriteCharPtr( "] /*Offset Next*/, " ) << endl; + + WriteTab( rOutStm, 4 ); + + // write ExecMethod, with standard name if not specified + if( !GetExecMethod().isEmpty() && + GetExecMethod() != "NoExec") + { + rOutStm.WriteCharPtr( "SFX_STUB_PTR(" ).WriteOString( rShellName ).WriteChar( ',' ) + .WriteOString( GetExecMethod() ).WriteChar( ')' ); + } + else + rOutStm.WriteCharPtr( "SFX_STUB_PTR_EXEC_NONE" ); + rOutStm.WriteChar( ',' ); + + // write StateMethod, with standard name if not specified + if( !GetStateMethod().isEmpty() && + GetStateMethod() != "NoState") + { + rOutStm.WriteCharPtr( "SFX_STUB_PTR(" ).WriteOString( rShellName ).WriteChar( ',' ) + .WriteOString( GetStateMethod() ).WriteChar( ')' ); + } + else + rOutStm.WriteCharPtr( "SFX_STUB_PTR_STATE_NONE" ); + + rOutStm.WriteChar( ',' ) << endl; + WriteTab( rOutStm, 4 ); + + // write flags + if( GetToggle() ) + rOutStm.WriteOString( MakeSlotName( SvHash_Toggle() ) ).WriteChar( '|' ); + if( GetAutoUpdate() ) + rOutStm.WriteOString( MakeSlotName( SvHash_AutoUpdate() ) ).WriteChar( '|' ); + if( GetAsynchron() ) + rOutStm.WriteOString( MakeSlotName( SvHash_Asynchron() ) ).WriteChar( '|' ); + if( GetRecordPerItem() ) + rOutStm.WriteOString( MakeSlotName( SvHash_RecordPerItem() ) ).WriteChar( '|' ); + if( GetRecordPerSet() ) + rOutStm.WriteOString( MakeSlotName( SvHash_RecordPerSet() ) ).WriteChar( '|' ); + if( GetNoRecord() ) + rOutStm.WriteOString( MakeSlotName( SvHash_NoRecord() ) ).WriteChar( '|' ); + if( GetRecordAbsolute() ) + rOutStm.WriteOString( MakeSlotName( SvHash_RecordAbsolute() ) ).WriteChar( '|' ); + if( GetMenuConfig() ) + rOutStm.WriteOString( MakeSlotName( SvHash_MenuConfig() ) ).WriteChar( '|' ); + if( GetToolBoxConfig() ) + rOutStm.WriteOString( MakeSlotName( SvHash_ToolBoxConfig() ) ).WriteChar( '|' ); + if( GetAccelConfig() ) + rOutStm.WriteOString( MakeSlotName( SvHash_AccelConfig() ) ).WriteChar( '|' ); + if( GetFastCall() ) + rOutStm.WriteOString( MakeSlotName( SvHash_FastCall() ) ).WriteChar( '|' ); + if( GetContainer() ) + rOutStm.WriteOString( MakeSlotName( SvHash_Container() ) ).WriteChar( '|' ); + if ( GetReadOnlyDoc() ) + rOutStm.WriteOString( MakeSlotName( SvHash_ReadOnlyDoc() ) ).WriteChar( '|' ); + rOutStm.WriteCharPtr( "SfxSlotMode::NONE" ); + + rOutStm.WriteChar( ',' ) << endl; + WriteTab( rOutStm, 4 ); + if ( GetDisableFlags().isEmpty() ) + rOutStm.WriteCharPtr( "SfxDisableFlags::NONE" ); + else + rOutStm.WriteOString( GetDisableFlags() ); + + // write attribute type + rOutStm.WriteChar( ',' ) << endl; + WriteTab( rOutStm, 4 ); + + SvMetaType * pT = GetType(); + if( !IsVariable() ) + { + SvMetaType * pRT = GetType()->GetReturnType(); + pT = pRT ? pRT : rBase.FindType( "SfxVoidItem" ); + } + + if( pT ) + { + assert(pT->IsItem()); + rOutStm.WriteOString( pT->GetName() ); + if( !SvIdlDataBase::FindType( pT, rBase.aUsedTypes ) ) + rBase.aUsedTypes.push_back( pT ); + } + else + rOutStm.WriteCharPtr( "SfxVoidItem not defined" ); + + { + rOutStm.WriteChar( ',' ) << endl; + WriteTab( rOutStm, 4 ); + rOutStm + .WriteOString( OString::number(nCount) ) + .WriteCharPtr( "/*Offset*/, " ); + + if( IsMethod() ) + { + SvMetaType * pType = GetType(); + sal_uLong nSCount = pType->GetAttrCount(); + rOutStm + .WriteOString( OString::number(nSCount) ) + .WriteCharPtr( "/*Count*/," ); + } + else + rOutStm.WriteCharPtr( "0," ); + + rOutStm.WriteCharPtr( " " ); + + // Method/Property flags + if( IsMethod() ) + rOutStm.WriteCharPtr( "SfxSlotMode::METHOD|" ); + + rOutStm.WriteCharPtr( "SfxSlotMode::NONE" ); + } + + { + rOutStm.WriteCharPtr( ",\"" ); + rOutStm.WriteOString( GetName() ); + rOutStm.WriteCharPtr( "\"" ); + } + + rOutStm.WriteCharPtr( " )," ) << endl; +} + +sal_uInt16 SvMetaSlot::WriteSlotParamArray( SvIdlDataBase & rBase, SvStream & rOutStm ) const +{ + if ( !GetExport() && !GetHidden() ) + return 0; + + if( IsMethod() ) + { + SvMetaType * pType = GetType(); + + if( !SvIdlDataBase::FindType( pType, rBase.aUsedTypes ) ) + rBase.aUsedTypes.push_back( pType ); + + const SvRefMemberList& rList = + pType->GetAttrList(); + for( sal_uLong n = 0; n < rList.size(); n++ ) + { + SvMetaAttribute * pPar = rList[n]; + SvMetaType * pPType = pPar->GetType(); + WriteTab( rOutStm, 1 ); + rOutStm.WriteCharPtr("{ (const SfxType*) &a") + // item type + .WriteOString(pPType->GetName()).WriteCharPtr("_Impl, ") + // parameter name + .WriteCharPtr("\"").WriteOString(pPar->GetName()).WriteCharPtr("\", ") + // slot id + .WriteOString(pPar->GetSlotId().getString()).WriteCharPtr(" },") << endl; + if( !SvIdlDataBase::FindType( pPType, rBase.aUsedTypes ) ) + rBase.aUsedTypes.push_back( pPType ); + } + return static_cast(rList.size()); + } + return 0; +} + +sal_uInt16 SvMetaSlot::WriteSlotMap( const OString& rShellName, sal_uInt16 nCount, + SvSlotElementList& rSlotList, + size_t nStart, + SvIdlDataBase & rBase, + SvStream & rOutStm ) +{ + // SlotId, if not specified generate from name + OString slotId = GetSlotId().getString(); + + sal_uInt16 nSCount = 0; + if( IsMethod() ) + { + SvMetaType * pType = GetType(); + nSCount = static_cast(pType->GetAttrCount()); + } + + WriteSlot( rShellName, nCount, slotId, rSlotList, nStart, rBase, rOutStm ); + return nSCount; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/idl/source/objects/types.cxx b/idl/source/objects/types.cxx new file mode 100644 index 000000000..9cb1684ca --- /dev/null +++ b/idl/source/objects/types.cxx @@ -0,0 +1,322 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include + +#include + +#include + +#include +#include +#include + +SvMetaAttribute::SvMetaAttribute() +{ +} + +SvMetaAttribute::SvMetaAttribute( SvMetaType * pType ) + : aType( pType ) +{ +} + +SvMetaType * SvMetaAttribute::GetType() const +{ + if( aType.is() || !GetRef() ) return aType.get(); + return static_cast(GetRef())->GetType(); +} + +const SvIdentifier & SvMetaAttribute::GetSlotId() const +{ + if( aSlotId.IsSet() || !GetRef() ) return aSlotId; + return static_cast(GetRef())->GetSlotId(); +} + +bool SvMetaAttribute::Test( SvTokenStream & rInStm ) +{ + if( GetType()->IsItem() && !GetSlotId().IsSet() ) + { + throw SvParseException( rInStm, "slot without id declared" ); + } + return true; +} + +bool SvMetaAttribute::ReadSvIdl( SvIdlDataBase & rBase, + SvTokenStream & rInStm ) +{ + sal_uInt32 nTokPos = rInStm.Tell(); + if( !GetType() ) + // no type in ctor passed on + aType = rBase.ReadKnownType( rInStm ); + bool bOk = false; + if( GetType() ) + { + ReadNameSvIdl( rInStm ); + aSlotId.ReadSvIdl( rBase, rInStm ); + + bOk = true; + SvToken& rTok = rInStm.GetToken(); + if( rTok.IsChar() && rTok.GetChar() == '(' ) + { + tools::SvRef xT(new SvMetaType() ); + xT->SetRef( GetType() ); + aType = xT; + bOk = aType->ReadMethodArgs( rBase, rInStm ); + } + if( bOk ) + bOk = SvMetaObject::ReadSvIdl( rBase, rInStm ); + } + else + { + SvToken& rTok = rInStm.GetToken(); + rBase.SetError( "unknown type of token. Each new SID needs an " + "item statement in an SDI file, eg. " + "SfxVoidItem FooItem " + rTok.GetTokenAsString() + + " ... which describes the slot more fully", rTok ); + } + + if( !bOk ) + rInStm.Seek( nTokPos ); + return bOk; +} + +sal_uLong SvMetaAttribute::MakeSfx( OStringBuffer& rAttrArray ) const +{ + SvMetaType * pType = GetType(); + DBG_ASSERT( pType, "no type for attribute" ); + SvMetaType * pBaseType = pType->GetBaseType(); + DBG_ASSERT( pBaseType, "no base type for attribute" ); + if( pBaseType->GetMetaTypeType() == MetaTypeType::Struct ) + return pBaseType->MakeSfx( rAttrArray ); + else + { + rAttrArray.append('{'); + rAttrArray.append(GetSlotId().getString()); + rAttrArray.append(",\""); + rAttrArray.append(GetName()); + rAttrArray.append("\"}"); + return 1; + } +} + +void SvMetaAttribute::Insert(SvSlotElementList&) +{ +} + +#define CTOR \ + : nType( MetaTypeType::Base ) \ + , bIsItem( false ) \ + +SvMetaType::SvMetaType() + CTOR +{ +} + +SvMetaType::SvMetaType( const OString& rName ) + CTOR +{ + SetName( rName ); +} + +SvMetaType::~SvMetaType() +{} + +void SvMetaType::SetType( MetaTypeType nT ) +{ + nType = nT; +} + +SvMetaType * SvMetaType::GetBaseType() const +{ + if( GetRef() && GetMetaTypeType() == MetaTypeType::Base ) + return static_cast(GetRef())->GetBaseType(); + return const_cast(this); +} + +SvMetaType * SvMetaType::GetReturnType() const +{ + DBG_ASSERT( GetMetaTypeType() == MetaTypeType::Method, "no method" ); + DBG_ASSERT( GetRef(), "no return type" ); + return static_cast(GetRef()); +} + +bool SvMetaType::ReadHeaderSvIdl( SvTokenStream & rInStm ) +{ + bool bOk = false; + sal_uInt32 nTokPos = rInStm.Tell(); + SvToken& rTok = rInStm.GetToken_Next(); + + if( rTok.Is( SvHash_interface() ) ) + { + SetType( MetaTypeType::Interface ); + bOk = ReadNameSvIdl( rInStm ); + } + else if( rTok.Is( SvHash_shell() ) ) + { + SetType( MetaTypeType::Shell ); + bOk = ReadNameSvIdl( rInStm ); + } + if( !bOk ) + rInStm.Seek( nTokPos ); + return bOk; +} + +bool SvMetaType::ReadSvIdl( SvIdlDataBase & rBase, + SvTokenStream & rInStm ) +{ + if( ReadHeaderSvIdl( rInStm ) ) + { + rBase.Write(OString('.')); + return SvMetaReference::ReadSvIdl( rBase, rInStm ); + } + return false; +} + +void SvMetaType::ReadContextSvIdl( SvIdlDataBase & rBase, + SvTokenStream & rInStm ) +{ + tools::SvRef xAttr( new SvMetaAttribute() ); + if( xAttr->ReadSvIdl( rBase, rInStm ) ) + { + if( xAttr->Test( rInStm ) ) + GetAttrList().push_back( xAttr.get() ); + } +} + +sal_uLong SvMetaType::MakeSfx( OStringBuffer& rAttrArray ) +{ + sal_uLong nC = 0; + + if( GetBaseType()->GetMetaTypeType() == MetaTypeType::Struct ) + { + sal_uLong nAttrCount = GetAttrCount(); + // write the single attributes + for( sal_uLong n = 0; n < nAttrCount; n++ ) + { + nC += aAttrList[n]->MakeSfx( rAttrArray ); + if( n +1 < nAttrCount ) + rAttrArray.append(", "); + } + } + return nC; +} + +void SvMetaType::WriteSfxItem( + const OString& rItemName, SvIdlDataBase const & rBase, SvStream& rOutStm ) +{ + WriteStars( rOutStm ); + OString aVarName = " a" + rItemName + "_Impl"; + + OStringBuffer aAttrArray(1024); + sal_uLong nAttrCount = MakeSfx( aAttrArray ); + OString aAttrCount( OString::number(nAttrCount)); + OString aTypeName = "SfxType" + aAttrCount; + + bool bExport = false, bReturn = false; + // these are exported from sfx library + if (rItemName == "SfxBoolItem" || + rItemName == "SfxStringItem" || + rItemName == "SfxUInt16Item" || + rItemName == "SfxUInt32Item" || + rItemName == "SfxVoidItem") + { + bExport = true; + if (!rBase.sSlotMapFile.endsWith("sfxslots.hxx")) + bReturn = true; + } + + rOutStm.WriteCharPtr( "extern " ); + if (bExport) + rOutStm.WriteCharPtr( "SFX2_DLLPUBLIC " ); + rOutStm.WriteOString( aTypeName ) + .WriteOString( aVarName ).WriteChar( ';' ) << endl; + if (bReturn) + return; + + // write the implementation part + rOutStm.WriteCharPtr( "#ifdef SFX_TYPEMAP" ) << endl; + rOutStm.WriteCharPtr( "#if !defined(_WIN32) && (defined(DISABLE_DYNLOADING) && (defined(ANDROID) || defined(IOS) || defined(LINUX)))" ) << endl; + rOutStm.WriteCharPtr( "__attribute__((__weak__))" ) << endl; + rOutStm.WriteCharPtr( "#endif" ) << endl; + rOutStm.WriteOString( aTypeName ).WriteOString( aVarName ) + .WriteCharPtr( " = " ) << endl; + rOutStm.WriteChar( '{' ) << endl; + + rOutStm.WriteCharPtr( "\tcreateSfxPoolItem<" ).WriteOString( rItemName ) + .WriteCharPtr(">, &typeid(").WriteOString( rItemName ).WriteCharPtr( "), " ); + rOutStm.WriteOString( aAttrCount ); + if( nAttrCount ) + { + rOutStm.WriteCharPtr( ", { " ); + // write the single attributes + rOutStm.WriteCharPtr( aAttrArray.getStr() ); + rOutStm.WriteCharPtr( " }" ); + } + rOutStm << endl; + rOutStm.WriteCharPtr( "};" ) << endl; + rOutStm.WriteCharPtr( "#endif" ) << endl << endl; +} + +void SvMetaType::WriteSfx( SvIdlDataBase & rBase, SvStream & rOutStm ) +{ + if( IsItem() ) + { + if( GetBaseType()->GetMetaTypeType() == MetaTypeType::Struct ) + GetBaseType()->WriteSfxItem( GetName(), rBase, rOutStm ); + else + WriteSfxItem( GetName(), rBase, rOutStm ); + } +} + +bool SvMetaType::ReadMethodArgs( SvIdlDataBase & rBase, + SvTokenStream & rInStm ) +{ + sal_uInt32 nTokPos = rInStm.Tell(); + if( rInStm.ReadIf( '(' ) ) + { + DoReadContextSvIdl( rBase, rInStm ); + if( rInStm.ReadIf( ')' ) ) + { + SetType( MetaTypeType::Method ); + return true; + } + } + rInStm.Seek( nTokPos ); + return false; +} + +SvMetaTypeString::SvMetaTypeString() + : SvMetaType( "String" ) +{ +} + +SvMetaEnumValue::SvMetaEnumValue() +{ +} + +SvMetaTypeEnum::SvMetaTypeEnum() +{ +} + +SvMetaTypevoid::SvMetaTypevoid() + : SvMetaType( "void" ) +{ +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/idl/source/prj/command.cxx b/idl/source/prj/command.cxx new file mode 100644 index 000000000..2e09351d5 --- /dev/null +++ b/idl/source/prj/command.cxx @@ -0,0 +1,303 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +char const * const SyntaxStrings[] = { +"basic-type:", +"\tvoid| char| int| float| double|", +"\tUINT16| INT16| UINT32| INT32| BOOL|", +"\tBYTE| String| SbxObject", +"", +"{ import \"filename\" }\n", +"module definition:", +"module", +"\tunique id range (ask MM)", +"modul-name", +"'['", +"\tSlotIdFile( \"filename\" )", +"']'", +"'{'", +"\t{ include \"filename\" }\n", + +"\titem definition:", +"\titem type item-name;\n", + +"\ttype definition:", +"\tstruct identifier", +"\t'{'", +"\t\t{ type identifier }", +"\t'}'", +"\t|", +"\tenum identifier", +"\t'{'", +"\t\t{ identifier, }", +"\t'}'", +"\t|", +"\ttypedef type identifier\n", + +"\titem-method:", +"\titem identifier item-method-args\n", + +"\titem-method-args:", +"\t( { item parameter-name SLOT_ID } )\n", + +"\tslot definition:", +"\titem identifier SLOT_ID [ item-method-args ]", +"\t'['\n", + +"\t\titem-method-args", +"\t\tAccelConfig, MenuConfig, ToolbarConfig", +"\t\tAutoUpdate", +"\t\tContainer", +"\t\tExecMethod = Identifier", +"\t\tExport*", +"\t\tFastCall", +"\t\tGet, Set", +"\t\tGroupId = Identifier", +"\t\tReadOnlyDoc*", +"\t\tRecordPerSet*, RecordPerItem, NoRecord", +"\t\tRecordAbsolute", +"\t\tStateMethod = Identifier", +"\t\tAsynchron", +"\t\tToggle", +"\t']'\n", + +"\tinterface definition:", +"\tshell | interface identifier ':' interface", +"\t'{'", +"\t\t{ slot }", +"\t'}'\n", +"---syntax example is sfx.idl---\n", +nullptr }; + +char const CommandLineSyntax[] = +"-fs\n" +"-fm\n" +"-help, ? @ response file\n" +" \n"; + +void Init() +{ + if( !GetIdlApp().pHashTable ) + GetIdlApp().pHashTable.reset( new SvStringHashTable ); + if( !GetIdlApp().pGlobalNames ) + GetIdlApp().pGlobalNames.reset( new SvGlobalHashNames() ); +} + +bool ReadIdl( SvIdlWorkingBase * pDataBase, const SvCommand & rCommand ) +{ + for( size_t n = 0; n < rCommand.aInFileList.size(); ++n ) + { + OUString aFileName ( rCommand.aInFileList[ n ] ); + pDataBase->AddDepFile(aFileName); + SvTokenStream aTokStm( aFileName ); + try { + SvIdlParser aParser(*pDataBase, aTokStm); + aParser.ReadSvIdl( rCommand.aPath ); + } catch (const SvParseException& ex) { + pDataBase->SetError(ex.aError); + pDataBase->WriteError(aTokStm); + return false; + } + } + return true; +} + +static bool ResponseFile( std::vector * pList, int argc, char ** argv ) +{ + // program name + pList->push_back( OUString::createFromAscii(*argv) ); + for( int i = 1; i < argc; i++ ) + { + if( '@' == **(argv +i) ) + { // when @, then response file + SvFileStream aStm( OUString::createFromAscii((*(argv +i)) +1), StreamMode::STD_READ ); + if( aStm.GetError() != ERRCODE_NONE ) + return false; + + OString aStr; + while( aStm.ReadLine( aStr ) ) + { + sal_uInt16 n = 0; + sal_uInt16 nPos = 1; + while( n != nPos ) + { + while( aStr[n] + && rtl::isAsciiWhiteSpace( + static_cast(aStr[n]) ) ) + n++; + nPos = n; + while( aStr[n] + && !rtl::isAsciiWhiteSpace( + static_cast(aStr[n]) ) ) + n++; + if( n != nPos ) + pList->push_back( OStringToOUString(aStr.copy(nPos, n - nPos), RTL_TEXTENCODING_ASCII_US) ); + } + } + } + else if( argv[ i ] ) + pList->push_back( OUString::createFromAscii( argv[ i ] ) ); + } + return true; +} + +SvCommand::SvCommand( int argc, char ** argv ) + : nVerbosity(1) +{ + std::vector aList; + + if( ResponseFile( &aList, argc, argv ) ) + { + for( size_t i = 1; i < aList.size(); i++ ) + { + OUString aParam( aList[ i ] ); + sal_Unicode aFirstChar( aParam[0] ); + if( '-' == aFirstChar ) + { + aParam = aParam.copy( 1 ); + aFirstChar = aParam[0]; + if( aFirstChar == 'F' || aFirstChar == 'f' ) + { + aParam = aParam.copy( 1 ); + aFirstChar = aParam[0]; + OUString aName( aParam.copy( 1 ) ); + if( 's' == aFirstChar ) + { // name of slot output + aSlotMapFile = aName; + } + else if( 'm' == aFirstChar ) + { // name of info file + aTargetFile = aName; + } + else if( 'x' == aFirstChar ) + { // name of IDL file for the CSV file + aExportFile = aName; + } + else if( 'M' == aFirstChar ) + { + m_DepFile = aName; + } + else + { + printf( + "unknown switch: %s\n", + OUStringToOString( + aParam, RTL_TEXTENCODING_UTF8).getStr()); + exit( -1 ); + } + } + else if( aParam.equalsIgnoreAsciiCase( "help" ) || aParam.equalsIgnoreAsciiCase( "?" ) ) + { // help + printf( "%s", CommandLineSyntax ); + } + else if( aParam.equalsIgnoreAsciiCase( "quiet" ) ) + { + nVerbosity = 0; + } + else if( aParam.equalsIgnoreAsciiCase( "verbose" ) ) + { + nVerbosity = 2; + } + else if( aParam.equalsIgnoreAsciiCase( "syntax" ) ) + { // help + int j = 0; + while(SyntaxStrings[j]) + printf("%s\n",SyntaxStrings[j++]); + } + else if (aParam == "isystem") + { + // ignore "-isystem" and following arg + if (i < aList.size()) + { + ++i; + } + } + else if (aParam.startsWith("isystem")) + { + // ignore args starting with "-isystem" + } + else if( aParam.startsWithIgnoreAsciiCase( "i" ) ) + { // define include paths + OUString aName( aParam.copy( 1 ) ); + if( !aPath.isEmpty() ) + aPath += OUStringChar(SAL_PATHSEPARATOR); + aPath += aName; + } + else if( aParam.startsWithIgnoreAsciiCase( "rsc" ) ) + { // first line in *.srs file + OSL_ENSURE(false, "does anything use this option, doesn't look like it belong here"); + if( !aList[ i + 1 ].isEmpty() ) + { + i++; + } + } + else + { + // temporary compatibility hack + printf( + "unknown switch: %s\n", + OUStringToOString( + aParam, RTL_TEXTENCODING_UTF8).getStr()); + exit( -1 ); + } + } + else + { + aInFileList.push_back( aParam ); + } + } + } + else + { + printf( "%s", CommandLineSyntax ); + } + + aList.clear(); + + OString aInc(getenv("INCLUDE")); + // append include environment variable + if( aInc.getLength() ) + { + if( !aPath.isEmpty() ) + aPath += OUStringChar(SAL_PATHSEPARATOR); + aPath += OStringToOUString(aInc, RTL_TEXTENCODING_ASCII_US); + } +} + +SvCommand::~SvCommand() +{ + // release String list + aInFileList.clear(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/idl/source/prj/database.cxx b/idl/source/prj/database.cxx new file mode 100644 index 000000000..7613e0a59 --- /dev/null +++ b/idl/source/prj/database.cxx @@ -0,0 +1,541 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + + +SvParseException::SvParseException( SvTokenStream const & rInStm, const OString& rError ) +{ + SvToken& rTok = rInStm.GetToken(); + aError = SvIdlError( rTok.GetLine(), rTok.GetColumn() ); + aError.SetText( rError ); +}; + +SvParseException::SvParseException( const OString& rError, SvToken const & rTok ) +{ + aError = SvIdlError( rTok.GetLine(), rTok.GetColumn() ); + aError.SetText( rError ); +}; + + +SvIdlDataBase::SvIdlDataBase( const SvCommand& rCmd ) + : bExport( false ) + , nUniqueId( 0 ) + , nVerbosity( rCmd.nVerbosity ) +{ + sSlotMapFile = rCmd.aSlotMapFile; +} + +SvIdlDataBase::~SvIdlDataBase() +{ + aIdFileList.clear(); +} + +#define ADD_TYPE( Name ) \ + aTypeList.push_back( new SvMetaType( SvHash_##Name()->GetName() ) ); + +SvRefMemberList& SvIdlDataBase::GetTypeList() +{ + if( aTypeList.empty() ) + { // fill initially + aTypeList.push_back( new SvMetaTypeString() ); + aTypeList.push_back( new SvMetaTypevoid() ); + + // MI: IDispatch::Invoke can not unsigned + ADD_TYPE( UINT16 ); + ADD_TYPE( INT16 ); + ADD_TYPE( UINT32 ); + ADD_TYPE( INT32 ); + ADD_TYPE( BOOL ); + ADD_TYPE( BYTE ); + ADD_TYPE( float ); + ADD_TYPE( double ); + ADD_TYPE( SbxObject ); + + // Attention! When adding types all binary data bases get incompatible + + } + return aTypeList; +} + +void SvIdlDataBase::SetError( const OString& rError, SvToken const & rTok ) +{ + if( rTok.GetLine() > 10000 ) + aError.SetText( "line count overflow" ); + + if( aError.nLine < rTok.GetLine() + || (aError.nLine == rTok.GetLine() && aError.nColumn < rTok.GetColumn()) ) + { + aError = SvIdlError( rTok.GetLine(), rTok.GetColumn() ); + aError.SetText( rError ); + } +} + +void SvIdlDataBase::SetAndWriteError( SvTokenStream & rInStm, const OString& rError ) +{ + SetError( rError, rInStm.GetToken() ); + WriteError( rInStm ); +} + +void SvIdlDataBase::Push( SvMetaObject * pObj ) +{ + GetStack().push_back( pObj ); +} + +bool SvIdlDataBase::FindId( const OString& rIdName, sal_uLong * pVal ) +{ + if( pIdTable ) + { + sal_uInt32 nHash; + if( pIdTable->Test( rIdName, &nHash ) ) + { + *pVal = pIdTable->Get( nHash )->GetValue(); + return true; + } + } + return false; +} + +void SvIdlDataBase::InsertId( const OString& rIdName, sal_uLong nVal ) +{ + if( !pIdTable ) + pIdTable.reset( new SvStringHashTable ); + + sal_uInt32 nHash; + pIdTable->Insert( rIdName, &nHash )->SetValue( nVal ); +} + +bool SvIdlDataBase::ReadIdFile( const OString& rOFileName ) +{ + OUString rFileName = OStringToOUString(rOFileName, RTL_TEXTENCODING_ASCII_US); + OUString aFullName; + osl::File::searchFileURL( rFileName, GetPath(), aFullName); + osl::FileBase::getSystemPathFromFileURL( aFullName, aFullName ); + + for ( size_t i = 0, n = aIdFileList.size(); i < n; ++i ) + if ( aIdFileList[ i ] == rFileName ) + return true; + + aIdFileList.push_back( rFileName ); + AddDepFile( aFullName ); + SvTokenStream aTokStm( aFullName ); + if( aTokStm.GetStream().GetError() != ERRCODE_NONE ) + return false; + + SvToken& rTok = aTokStm.GetToken_Next(); + + while( !rTok.IsEof() ) + { + if( rTok.IsChar() && rTok.GetChar() == '#' ) + { + rTok = aTokStm.GetToken_Next(); + if( rTok.Is( SvHash_define() ) ) + { + rTok = aTokStm.GetToken_Next(); + OString aDefName; + if( !rTok.IsIdentifier() ) + throw SvParseException( "unexpected token after define", rTok ); + aDefName = rTok.GetString(); + + sal_uLong nVal = 0; + bool bOk = true; + while( bOk ) + { + rTok = aTokStm.GetToken_Next(); + if (rTok.GetTokenAsString().startsWith("TypedWhichId")) + { + rTok = aTokStm.GetToken_Next(); + if( !rTok.IsChar() || rTok.GetChar() != '<') + throw SvParseException( "expected '<'", rTok ); + rTok = aTokStm.GetToken_Next(); + if( !rTok.IsIdentifier() ) + throw SvParseException( "expected identifier", rTok ); + rTok = aTokStm.GetToken_Next(); + if( !rTok.IsChar() || rTok.GetChar() != '>') + throw SvParseException( "expected '<'", rTok ); + rTok = aTokStm.GetToken_Next(); + } + else if( rTok.IsIdentifier() ) + { + sal_uLong n; + if( FindId( rTok.GetString(), &n ) ) + nVal += n; + else + bOk = false; + } + else if( rTok.IsChar() ) + { + if( rTok.GetChar() == '-' + || rTok.GetChar() == '/' + || rTok.GetChar() == '*' + || rTok.GetChar() == '&' + || rTok.GetChar() == '|' + || rTok.GetChar() == '^' + || rTok.GetChar() == '~' ) + { + throw SvParseException( "unknown operator '" + OStringChar(rTok.GetChar()) + "'in define", rTok ); + } + if( rTok.GetChar() != '+' + && rTok.GetChar() != '(' + && rTok.GetChar() != ')' ) + // only + is allowed, parentheses are immaterial + // because + is commutative + break; + } + else if( rTok.IsInteger() ) + { + nVal += rTok.GetNumber(); + } + else + break; + } + if( bOk ) + { + InsertId( aDefName, nVal ); + } + } + else if( rTok.Is( SvHash_include() ) ) + { + rTok = aTokStm.GetToken_Next(); + OStringBuffer aNameBuf(128); + if( rTok.IsString() ) + aNameBuf.append(rTok.GetString()); + else if( rTok.IsChar() && rTok.GetChar() == '<' ) + { + rTok = aTokStm.GetToken_Next(); + while( !rTok.IsEof() + && !(rTok.IsChar() && rTok.GetChar() == '>') ) + { + aNameBuf.append(rTok.GetTokenAsString()); + rTok = aTokStm.GetToken_Next(); + } + if( rTok.IsEof() ) + { + throw SvParseException("unexpected eof in #include", rTok); + } + } + OString aName(aNameBuf.makeStringAndClear()); + if (aName == "sfx2/groupid.hxx") + { + // contains C++ code which we cannot parse + // we special-case this by defining a macro internally in... + } + else if (aName == "svl/typedwhich.hxx") + { + // contains C++ code which we cannot parse + } + else if (!ReadIdFile(aName)) + { + throw SvParseException("cannot read file: " + aName, rTok); + } + } + } + else + rTok = aTokStm.GetToken_Next(); + } + return true; +} + +SvMetaType * SvIdlDataBase::FindType( const SvMetaType * pPType, + SvRefMemberList& rList ) +{ + for (auto const& elem : rList) + if( elem == pPType ) + return elem; + return nullptr; +} + +SvMetaType * SvIdlDataBase::FindType( const OString& rName ) +{ + for (auto const& elem : aTypeList) + if( rName == elem->GetName() ) + return elem; + return nullptr; +} + +SvMetaType * SvIdlDataBase::ReadKnownType( SvTokenStream & rInStm ) +{ + sal_uInt32 nTokPos = rInStm.Tell(); + SvToken& rTok = rInStm.GetToken_Next(); + + if( rTok.IsIdentifier() ) + { + const OString& aName = rTok.GetString(); + for( const auto& aType : GetTypeList() ) + { + if( aType->GetName() == aName ) + { + return aType; + } + } + } + rInStm.Seek( nTokPos ); + return nullptr; +} + +SvMetaAttribute * SvIdlDataBase::ReadKnownAttr +( + SvTokenStream & rInStm, + SvMetaType * pType /* If pType == NULL, then the type has + still to be read. */ +) +{ + sal_uInt32 nTokPos = rInStm.Tell(); + + if( !pType ) + pType = ReadKnownType( rInStm ); + + if( !pType ) + { + // otherwise SlotId? + SvToken& rTok = rInStm.GetToken_Next(); + if( rTok.IsIdentifier() ) + { + sal_uLong n; + if( FindId( rTok.GetString(), &n ) ) + { + for( sal_uLong i = 0; i < aSlotList.size(); i++ ) + { + SvMetaSlot * pSlot = aSlotList[i]; + if( pSlot->GetSlotId().getString() == rTok.GetString() ) + return pSlot; + } + } + + OStringBuffer aStr("Not found : "); + aStr.append(rTok.GetString()); + OSL_FAIL(aStr.getStr()); + } + } + + rInStm.Seek( nTokPos ); + return nullptr; +} + +SvMetaAttribute* SvIdlDataBase::FindKnownAttr( const SvIdentifier& rId ) +{ + sal_uLong n; + if( FindId( rId.getString(), &n ) ) + { + for( sal_uLong i = 0; i < aSlotList.size(); i++ ) + { + SvMetaSlot * pSlot = aSlotList[i]; + if( pSlot->GetSlotId().getString() == rId.getString() ) + return pSlot; + } + } + + return nullptr; +} + +SvMetaClass * SvIdlDataBase::ReadKnownClass( SvTokenStream & rInStm ) +{ + sal_uInt32 nTokPos = rInStm.Tell(); + SvToken& rTok = rInStm.GetToken_Next(); + + if( rTok.IsIdentifier() ) + { + SvMetaClass* p = FindKnownClass(rTok.GetString()); + if (p) + return p; + } + + rInStm.Seek( nTokPos ); + return nullptr; +} + +SvMetaClass * SvIdlDataBase::FindKnownClass( const OString& aName ) +{ + for( sal_uLong n = 0; n < aClassList.size(); n++ ) + { + SvMetaClass * pClass = aClassList[n]; + if( pClass->GetName() == aName ) + return pClass; + } + return nullptr; +} + +void SvIdlDataBase::Write(const OString& rText) const +{ + if( nVerbosity != 0 ) + fprintf( stdout, "%s", rText.getStr() ); +} + +void SvIdlDataBase::WriteError( SvTokenStream & rInStm ) +{ + // error treatment + OUString aFileName( rInStm.GetFileName() ); + OStringBuffer aErrorText; + sal_uLong nRow = 0, nColumn = 0; + + rInStm.SeekToMax(); + SvToken& rTok = rInStm.GetToken(); + + // error position + nRow = rTok.GetLine(); + nColumn = rTok.GetColumn(); + + if( aError.IsError() ) + { // error set + // search error token + // error text + if( !aError.GetText().isEmpty() ) + { + aErrorText.append("may be <"); + aErrorText.append(aError.GetText()); + } + SvToken * pPrevTok = nullptr; + while( &rTok != pPrevTok ) + { + pPrevTok = &rTok; + if( rTok.GetLine() == aError.nLine + && rTok.GetColumn() == aError.nColumn ) + break; + rTok = rInStm.GetToken_PrevAll(); + } + + // error position + aErrorText.append("> at ( "); + aErrorText.append(static_cast(aError.nLine)); + aErrorText.append(", "); + aErrorText.append(static_cast(aError.nColumn)); + aErrorText.append(" )"); + + // reset error + aError = SvIdlError(); + } + + // error treatment + fprintf( stderr, "\n%s --- %s: ( %" SAL_PRIuUINTPTR ", %" SAL_PRIuUINTPTR " )\n", + OUStringToOString(aFileName, RTL_TEXTENCODING_UTF8).getStr(), + "error", nRow, nColumn ); + + if( !aErrorText.isEmpty() ) + { // error set + fprintf( stderr, "\t%s\n", aErrorText.getStr() ); + } + + // look for identifier close by + if( !rTok.IsIdentifier() ) + { + rInStm.GetToken_PrevAll(); + rTok = rInStm.GetToken(); + } + if( rTok.IsIdentifier() ) + { + OString aN = GetIdlApp().pHashTable->GetNearString( rTok.GetString() ); + if( !aN.isEmpty() ) + fprintf( stderr, "%s versus %s\n", rTok.GetString().getStr(), aN.getStr() ); + } +} + +SvIdlWorkingBase::SvIdlWorkingBase(const SvCommand& rCmd) : SvIdlDataBase(rCmd) +{ +} + + +bool SvIdlWorkingBase::WriteSfx( SvStream & rOutStm ) +{ + if( rOutStm.GetError() != ERRCODE_NONE ) + return false; + + // reset all tmp variables for writing + WriteReset(); + SvMemoryStream aTmpStm( 256000, 256000 ); + sal_uLong n; + for( n = 0; n < GetModuleList().size(); n++ ) + { + SvMetaModule * pModule = GetModuleList()[n]; + pModule->WriteSfx( *this, aTmpStm ); + aTmpStm.Seek( 0 ); + } + for( n = 0; n < aUsedTypes.size(); n++ ) + { + SvMetaType * pType = aUsedTypes[n]; + pType->WriteSfx( *this, rOutStm ); + } + aUsedTypes.clear(); + rOutStm.WriteStream( aTmpStm ); + return true; +} + +void SvIdlDataBase::StartNewFile( const OUString& rName ) +{ + bExport = aExportFile.equalsIgnoreAsciiCase( rName ); + assert ( !bExport ); +} + +void SvIdlDataBase::AppendSlot( SvMetaSlot *pSlot ) +{ + aSlotList.push_back( pSlot ); + assert ( !bExport ); +} + +void SvIdlDataBase::AddDepFile(OUString const& rFileName) +{ + m_DepFiles.insert(rFileName); +} + +namespace { + +struct WriteDep +{ + SvFileStream & m_rStream; + explicit WriteDep(SvFileStream & rStream) : m_rStream(rStream) { } + void operator() (OUString const& rItem) + { + m_rStream.WriteCharPtr( " \\\n " ); + m_rStream.WriteOString( OUStringToOString(rItem, RTL_TEXTENCODING_UTF8) ); + } +}; + +// write a dummy target for one included file, so the incremental build does +// not break with "No rule to make target" if the included file is removed +struct WriteDummy +{ + SvFileStream & m_rStream; + explicit WriteDummy(SvFileStream & rStream) : m_rStream(rStream) { } + void operator() (OUString const& rItem) + { + m_rStream.WriteOString( OUStringToOString(rItem, RTL_TEXTENCODING_UTF8) ); + m_rStream.WriteCharPtr( " :\n\n" ); + } +}; + +} + +void SvIdlDataBase::WriteDepFile( + SvFileStream & rStream, OUString const& rTarget) +{ + rStream.WriteOString( OUStringToOString(rTarget, RTL_TEXTENCODING_UTF8) ); + rStream.WriteCharPtr( " :" ); + ::std::for_each(m_DepFiles.begin(), m_DepFiles.end(), WriteDep(rStream)); + rStream.WriteCharPtr( "\n\n" ); + ::std::for_each(m_DepFiles.begin(), m_DepFiles.end(), WriteDummy(rStream)); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/idl/source/prj/globals.cxx b/idl/source/prj/globals.cxx new file mode 100644 index 000000000..5231076e4 --- /dev/null +++ b/idl/source/prj/globals.cxx @@ -0,0 +1,92 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include +#include + +#include +#include + +namespace { + +struct TheIdlDll: public rtl::Static {}; + +} + +IdlDll & GetIdlApp() +{ + return TheIdlDll::get(); +} + +IdlDll::IdlDll() +{} + +IdlDll::~IdlDll() +{ +} + +static SvStringHashEntry * INS( const OString& rName ) +{ + sal_uInt32 nIdx; + GetIdlApp().pHashTable->Insert( rName, &nIdx ); + return GetIdlApp().pHashTable->Get( nIdx ); +} +#define A_ENTRY( Name ) , MM_##Name( INS( #Name ) ) + +SvGlobalHashNames::SvGlobalHashNames() + : MM_module( INS( "module" ) ) + , MM_interface( INS( "interface" ) ) + , MM_shell( INS( "shell" ) ) + , MM_Toggle( INS( "Toggle" ) ) + , MM_AutoUpdate( INS( "AutoUpdate" ) ) + , MM_Asynchron( INS( "Asynchron" ) ) + A_ENTRY(RecordPerSet) + A_ENTRY(RecordPerItem) + A_ENTRY(NoRecord) + A_ENTRY(RecordAbsolute) + A_ENTRY(enum) + A_ENTRY(UINT16) + A_ENTRY(INT16) + A_ENTRY(UINT32) + A_ENTRY(INT32) + A_ENTRY(BOOL) + A_ENTRY(BYTE) + A_ENTRY(float) + A_ENTRY(double) + A_ENTRY(item) + A_ENTRY(import) + A_ENTRY(SlotIdFile) + A_ENTRY(include) + A_ENTRY(ExecMethod) + A_ENTRY(StateMethod) + A_ENTRY(GroupId) + A_ENTRY(Export) + A_ENTRY(define) + A_ENTRY(MenuConfig) + A_ENTRY(ToolBoxConfig) + A_ENTRY(AccelConfig) + A_ENTRY(FastCall) + A_ENTRY(SbxObject) + A_ENTRY(Container) + A_ENTRY(ReadOnlyDoc) + A_ENTRY(struct) + A_ENTRY(DisableFlags) +{} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/idl/source/prj/parser.cxx b/idl/source/prj/parser.cxx new file mode 100644 index 000000000..dc5bb4f14 --- /dev/null +++ b/idl/source/prj/parser.cxx @@ -0,0 +1,590 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include + +#include + +#include +#include +#include +#include + +void SvIdlParser::ReadSvIdl( const OUString & rPath ) +{ + rBase.SetPath(rPath); // only valid for this iteration + SvToken& rTok = rInStm.GetToken(); + + while( true ) + { + rTok = rInStm.GetToken(); + if( rTok.IsEof() ) + return; + + Read( SvHash_module() ); + tools::SvRef aModule = new SvMetaModule; + ReadModuleHeader(*aModule); + rBase.GetModuleList().push_back( aModule.get() ); + } +} + +void SvIdlParser::ReadModuleHeader(SvMetaModule& rModule) +{ + OString aName = ReadIdentifier(); + rModule.SetName( aName ); + rBase.Push( &rModule ); // onto the context stack + ReadModuleBody(rModule); + rBase.GetStack().pop_back(); // remove from stack +} + +void SvIdlParser::ReadModuleBody(SvMetaModule& rModule) +{ + if( ReadIf( '[' ) ) + { + while( true ) + { + OString aSlotIdFile; + if( !ReadStringSvIdl( SvHash_SlotIdFile(), rInStm, aSlotIdFile ) ) + break; + if( !rBase.ReadIdFile( aSlotIdFile ) ) + { + throw SvParseException( rInStm, "cannot read file: " + aSlotIdFile ); + } + ReadIfDelimiter(); + } + Read( ']' ); + } + + if( !ReadIf( '{' ) ) + return; + + sal_uInt32 nBeginPos = 0; + while( nBeginPos != rInStm.Tell() ) + { + nBeginPos = rInStm.Tell(); + ReadModuleElement( rModule ); + ReadIfDelimiter(); + } + Read( '}' ); +} + +void SvIdlParser::ReadModuleElement( SvMetaModule& rModule ) +{ + if( ReadIf( SvHash_interface() ) ) + { + ReadInterfaceOrShell(rModule, MetaTypeType::Interface); + } + else if( ReadIf( SvHash_shell() ) ) + { + ReadInterfaceOrShell(rModule, MetaTypeType::Shell); + } + else if( ReadIf( SvHash_enum() ) ) + { + ReadEnum(); + } + else if( ReadIf( SvHash_item() ) ) + { + ReadItem(); + } + else if( ReadIf( SvHash_struct() ) ) + { + ReadStruct(); + } + else if( ReadIf( SvHash_include() ) ) + { + ReadInclude(rModule); + } + else + { + tools::SvRef xSlot( new SvMetaSlot() ); + + if (ReadSlot(*xSlot)) + { + if( xSlot->Test( rInStm ) ) + { + // announce globally + rBase.AppendSlot( xSlot.get() ); + } + } + } +} + +void SvIdlParser::ReadInclude( SvMetaModule& rModule ) +{ + sal_uInt32 nTokPos = rInStm.Tell(); + bool bOk = false; + OUString aFullName(OStringToOUString(ReadString(), RTL_TEXTENCODING_ASCII_US)); + rBase.StartNewFile( aFullName ); + osl::FileBase::RC searchError = osl::File::searchFileURL(aFullName, rBase.GetPath(), aFullName); + if( osl::FileBase::E_None != searchError ) + { + OString aStr = "cannot find file:" + + OUStringToOString(aFullName, RTL_TEXTENCODING_UTF8); + throw SvParseException(aStr, rInStm.GetToken()); + } + osl::FileBase::getSystemPathFromFileURL( aFullName, aFullName ); + rBase.AddDepFile( aFullName ); + SvTokenStream aTokStm( aFullName ); + if( ERRCODE_NONE != aTokStm.GetStream().GetError() ) + { + OString aStr = "cannot open file: " + + OUStringToOString(aFullName, RTL_TEXTENCODING_UTF8); + throw SvParseException(aStr, rInStm.GetToken()); + } + // rescue error from old file + SvIdlError aOldErr = rBase.GetError(); + // reset error + rBase.SetError( SvIdlError() ); + + try { + SvIdlParser aIncludeParser( rBase, aTokStm ); + sal_uInt32 nBeginPos = 0xFFFFFFFF; // can not happen with Tell + while( nBeginPos != aTokStm.Tell() ) + { + nBeginPos = aTokStm.Tell(); + aIncludeParser.ReadModuleElement(rModule); + aTokStm.ReadIfDelimiter(); + } + } catch (const SvParseException& ex) { + rBase.SetError(ex.aError); + rBase.WriteError(aTokStm); + } + bOk = aTokStm.GetToken().IsEof(); + if( !bOk ) + { + rBase.WriteError( aTokStm ); + } + // recover error from old file + rBase.SetError( aOldErr ); + if( !bOk ) + rInStm.Seek( nTokPos ); +} + +void SvIdlParser::ReadStruct() +{ + tools::SvRef xStruct(new SvMetaType() ); + xStruct->SetType( MetaTypeType::Struct ); + xStruct->SetName( ReadIdentifier() ); + Read( '{' ); + while( true ) + { + tools::SvRef xAttr( new SvMetaAttribute() ); + xAttr->aType = ReadKnownType(); + xAttr->SetName(ReadIdentifier()); + xAttr->aSlotId.setString(ReadIdentifier()); + sal_uLong n; + if( !rBase.FindId( xAttr->aSlotId.getString(), &n ) ) + throw SvParseException( rInStm, "no value for identifier <" + xAttr->aSlotId.getString() + "> " ); + xAttr->aSlotId.SetValue(n); + xStruct->GetAttrList().push_back( xAttr.get() ); + if( !ReadIfDelimiter() ) + break; + if( rInStm.GetToken().IsChar() && rInStm.GetToken().GetChar() == '}') + break; + } + Read( '}' ); + ReadDelimiter(); + // announce globally + rBase.GetTypeList().push_back( xStruct.get() ); +} + +void SvIdlParser::ReadItem() +{ + tools::SvRef xItem(new SvMetaType() ); + xItem->SetItem(true); + xItem->SetRef( ReadKnownType() ); + xItem->SetName( ReadIdentifier() ); + // announce globally + rBase.GetTypeList().push_back( xItem.get() ); +} + +void SvIdlParser::ReadEnum() +{ + tools::SvRef xEnum( new SvMetaTypeEnum() ); + xEnum->SetType( MetaTypeType::Enum ); + xEnum->SetName( ReadIdentifier() ); + + Read('{'); + while( true ) + { + ReadEnumValue( *xEnum ); + if( !ReadIfDelimiter() ) + break; + } + Read( '}' ); + // announce globally + rBase.GetTypeList().push_back( xEnum.get() ); +} + +static OString getCommonSubPrefix(const OString &rA, const OString &rB) +{ + sal_Int32 nMax = std::min(rA.getLength(), rB.getLength()); + sal_Int32 nI = 0; + while (nI < nMax) + { + if (rA[nI] != rB[nI]) + break; + ++nI; + } + return rA.copy(0, nI); +} + +void SvIdlParser::ReadEnumValue( SvMetaTypeEnum& rEnum ) +{ + tools::SvRef aEnumVal = new SvMetaEnumValue(); + aEnumVal->SetName( ReadIdentifier() ); + if( rEnum.aEnumValueList.empty() ) + { + // the first + rEnum.aPrefix = aEnumVal->GetName(); + } + else + { + rEnum.aPrefix = getCommonSubPrefix(rEnum.aPrefix, aEnumVal->GetName()); + } + rEnum.aEnumValueList.push_back( aEnumVal.get() ); +} + +void SvIdlParser::ReadInterfaceOrShell( SvMetaModule& rModule, MetaTypeType aMetaTypeType ) +{ + tools::SvRef aClass( new SvMetaClass() ); + + aClass->SetType( aMetaTypeType ); + + aClass->SetName( ReadIdentifier() ); + + if( ReadIf( ':' ) ) + { + aClass->aSuperClass = ReadKnownClass(); + } + if( ReadIf( '{' ) ) + { + sal_uInt32 nBeginPos = 0; // can not happen with Tell + while( nBeginPos != rInStm.Tell() ) + { + nBeginPos = rInStm.Tell(); + ReadInterfaceOrShellEntry(*aClass); + ReadIfDelimiter(); + } + Read( '}' ); + } + rModule.aClassList.push_back( aClass.get() ); + // announce globally + rBase.GetClassList().push_back( aClass.get() ); +} + +void SvIdlParser::ReadInterfaceOrShellEntry(SvMetaClass& rClass) +{ + if( ReadIf( SvHash_import() ) ) + { + SvMetaClass * pClass = ReadKnownClass(); + SvClassElement aEle(pClass); + SvToken& rTok = rInStm.GetToken(); + if( rTok.IsString() ) + { + aEle.SetPrefix( rTok.GetString() ); + rInStm.GetToken_Next(); + } + rClass.aClassElementList.push_back( aEle ); + } + else + { + SvMetaType * pType = rBase.ReadKnownType( rInStm ); + tools::SvRef xAttr; + bool bOk = false; + if( !pType || pType->IsItem() ) + { + xAttr = new SvMetaSlot( pType ); + bOk = ReadSlot(static_cast(*xAttr)); + } + else + { + xAttr = new SvMetaAttribute( pType ); + ReadInterfaceOrShellMethod(*xAttr); + bOk = true; + } + if( bOk ) + bOk = xAttr->Test( rInStm ); + if( bOk ) + bOk = rClass.TestAttribute( rBase, rInStm, *xAttr ); + if( bOk ) + { + if( !xAttr->GetSlotId().IsSet() ) + xAttr->SetSlotId( SvIdentifier(rBase.GetUniqueId()) ); + rClass.aAttrList.push_back( xAttr.get() ); + } + } +} + +bool SvIdlParser::ReadSlot(SvMetaSlot& rSlot) +{ + sal_uInt32 nTokPos = rInStm.Tell(); + bool bOk = true; + + SvMetaAttribute * pAttr = rBase.ReadKnownAttr( rInStm, rSlot.GetType() ); + if( pAttr ) + { + SvMetaSlot * pKnownSlot = dynamic_cast( pAttr ); + if( !pKnownSlot ) + throw SvParseException( rInStm, "attribute " + pAttr->GetName() + " is method or variable but not a slot" ); + rSlot.SetRef( pKnownSlot ); + rSlot.SetName( pKnownSlot->GetName() ); + if( ReadIf( '[' ) ) + { + sal_uInt32 nBeginPos = 0; // can not happen with Tell + while( nBeginPos != rInStm.Tell() ) + { + nBeginPos = rInStm.Tell(); + ReadSlotAttribute(rSlot); + ReadIfDelimiter(); + } + Read( ']' ); + } + } + else + { + bOk = rSlot.SvMetaAttribute::ReadSvIdl( rBase, rInStm ); + SvMetaAttribute *pAttr2 = rBase.FindKnownAttr( rSlot.GetSlotId() ); + if( pAttr2 ) + { + SvMetaSlot * pKnownSlot = dynamic_cast( pAttr2 ); + if( !pKnownSlot ) + throw SvParseException( rInStm, "attribute " + pAttr2->GetName() + " is method or variable but not a slot" ); + rSlot.SetRef( pKnownSlot ); + // names may differ, because explicitly given + if ( pKnownSlot->GetName() != rSlot.GetName() ) + throw SvParseException( rInStm, "Illegal definition!" ); + } + } + + if( !bOk ) + rInStm.Seek( nTokPos ); + + return bOk; +} + +void SvIdlParser::ReadSlotAttribute( SvMetaSlot& rSlot ) +{ + ReadIfIdAttribute(rSlot.aGroupId, SvHash_GroupId() ); + ReadIfIdAttribute(rSlot.aExecMethod, SvHash_ExecMethod() ); + ReadIfIdAttribute(rSlot.aStateMethod, SvHash_StateMethod() ); + ReadStringSvIdl( SvHash_DisableFlags(), rInStm, rSlot.aDisableFlags ); + ReadIfBoolAttribute(rSlot.aReadOnlyDoc, SvHash_ReadOnlyDoc() ); + ReadIfBoolAttribute(rSlot.aExport, SvHash_Export() ); + + ReadIfBoolAttribute(rSlot.aToggle, SvHash_Toggle() ); + ReadIfBoolAttribute(rSlot.aAutoUpdate, SvHash_AutoUpdate() ); + ReadIfBoolAttribute(rSlot.aAsynchron, SvHash_Asynchron() ); + ReadIfBoolAttribute(rSlot.aRecordAbsolute, SvHash_RecordAbsolute() ); + + if( ReadIfBoolAttribute(rSlot.aRecordPerItem, SvHash_RecordPerItem()) ) + { + if (rSlot.aRecordPerSet.IsSet() || rSlot.aNoRecord.IsSet()) + throw SvParseException(rInStm, "conflicting attributes"); + rSlot.SetRecordPerItem( rSlot.aRecordPerItem ); + } + if( ReadIfBoolAttribute(rSlot.aRecordPerSet, SvHash_RecordPerSet() ) ) + { + if (rSlot.aRecordPerItem.IsSet() || rSlot.aNoRecord.IsSet()) + throw SvParseException(rInStm, "conflicting attributes"); + rSlot.SetRecordPerSet( rSlot.aRecordPerSet ); + } + if( ReadIfBoolAttribute(rSlot.aNoRecord, SvHash_NoRecord() ) ) + { + if (rSlot.aRecordPerItem.IsSet() || rSlot.aRecordPerSet.IsSet()) + throw SvParseException(rInStm, "conflicting attributes"); + rSlot.SetNoRecord( rSlot.aNoRecord ); + } + + ReadIfBoolAttribute(rSlot.aMenuConfig, SvHash_MenuConfig() ); + ReadIfBoolAttribute(rSlot.aToolBoxConfig, SvHash_ToolBoxConfig() ); + ReadIfBoolAttribute(rSlot.aAccelConfig, SvHash_AccelConfig() ); + + ReadIfBoolAttribute(rSlot.aFastCall, SvHash_FastCall() ); + ReadIfBoolAttribute(rSlot.aContainer, SvHash_Container() ); +} + +void SvIdlParser::ReadInterfaceOrShellMethod( SvMetaAttribute& rAttr ) +{ + rAttr.SetName( ReadIdentifier() ); + ReadSlotId( rAttr.aSlotId ); + + // read method arguments + Read( '(' ); + tools::SvRef xT(new SvMetaType() ); + xT->SetRef(rAttr.GetType() ); + rAttr.aType = xT; + rAttr.aType->SetType( MetaTypeType::Method ); + if (ReadIf(')')) + return; + + while (true) + { + tools::SvRef xParamAttr( new SvMetaAttribute() ); + xParamAttr->aType = ReadKnownType(); + xParamAttr->SetName( ReadIdentifier() ); + ReadSlotId(xParamAttr->aSlotId); + rAttr.aType->GetAttrList().push_back( xParamAttr.get() ); + if (!ReadIfDelimiter()) + break; + } + Read(')'); +} + +void SvIdlParser::ReadSlotId(SvIdentifier& rSlotId) +{ + rSlotId.setString( ReadIdentifier() ); + sal_uLong n; + if( !rBase.FindId( rSlotId.getString(), &n ) ) + throw SvParseException( rInStm, "no value for identifier <" + rSlotId.getString() + "> " ); + rSlotId.SetValue(n); +} + +SvMetaClass * SvIdlParser::ReadKnownClass() +{ + OString aName(ReadIdentifier()); + SvMetaClass* pClass = rBase.FindKnownClass( aName ); + if( !pClass ) + throw SvParseException( rInStm, "unknown class" ); + return pClass; +} + +SvMetaType * SvIdlParser::ReadKnownType() +{ + OString aName = ReadIdentifier(); + for( const auto& aType : rBase.GetTypeList() ) + { + if( aType->GetName() == aName ) + return aType; + } + throw SvParseException( rInStm, "wrong typedef: "); +} + +bool SvIdlParser::ReadIfBoolAttribute( SvBOOL& rBool, SvStringHashEntry const * pName ) +{ + sal_uInt32 nTokPos = rInStm.Tell(); + SvToken& rTok = rInStm.GetToken_Next(); + + if( rTok.Is( pName ) ) + { + if( rInStm.ReadIf( '=' ) ) + { + rTok = rInStm.GetToken(); + if( !rTok.IsBool() ) + throw SvParseException(rInStm, "xxx"); + rBool = rTok.GetBool(); + rInStm.GetToken_Next(); + } + else + rBool = true; //default action set to TRUE + return true; + } + rInStm.Seek( nTokPos ); + return false; +} + +void SvIdlParser::ReadIfIdAttribute( SvIdentifier& rIdentifier, SvStringHashEntry const * pName ) +{ + sal_uInt32 nTokPos = rInStm.Tell(); + SvToken& rTok = rInStm.GetToken_Next(); + + if( rTok.Is( pName ) ) + { + if( rInStm.ReadIf( '=' ) ) + { + rTok = rInStm.GetToken(); + if( !rTok.IsIdentifier() ) + throw SvParseException(rInStm, "expected identifier"); + rIdentifier.setString(rTok.GetString()); + rInStm.GetToken_Next(); + } + } + else + rInStm.Seek( nTokPos ); +} + +void SvIdlParser::ReadDelimiter() +{ + if( !ReadIfDelimiter() ) + throw SvParseException(rInStm, "expected delimiter"); +} + +bool SvIdlParser::ReadIfDelimiter() +{ + if( rInStm.GetToken().IsChar() + && (';' == rInStm.GetToken().GetChar() + || ',' == rInStm.GetToken().GetChar()) ) + { + rInStm.GetToken_Next(); + return true; + } + return false; +} + +OString SvIdlParser::ReadIdentifier() +{ + SvToken& rTok = rInStm.GetToken(); + if( !rTok.IsIdentifier() ) + throw SvParseException("expected identifier", rTok); + rInStm.GetToken_Next(); + return rTok.GetString(); +} + +OString SvIdlParser::ReadString() +{ + SvToken& rTok = rInStm.GetToken(); + if( !rTok.IsString() ) + throw SvParseException("expected string", rTok); + rInStm.GetToken_Next(); + return rTok.GetString(); +} + +void SvIdlParser::Read(char cChar) +{ + if( !ReadIf(cChar) ) + throw SvParseException(rInStm, "expected char '" + OStringChar(cChar) + "'"); +} + +bool SvIdlParser::ReadIf(char cChar) +{ + if( rInStm.GetToken().IsChar() && rInStm.GetToken().GetChar() == cChar ) + { + rInStm.GetToken_Next(); + return true; + } + return false; +} + +void SvIdlParser::Read(SvStringHashEntry const * entry) +{ + if( !rInStm.GetToken().Is(entry) ) + throw SvParseException("expected " + entry->GetName(), rInStm.GetToken()); + rInStm.GetToken_Next(); +} + +bool SvIdlParser::ReadIf(SvStringHashEntry const * entry) +{ + if( rInStm.GetToken().Is(entry) ) + { + rInStm.GetToken_Next(); + return true; + } + return false; +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/idl/source/prj/svidl.cxx b/idl/source/prj/svidl.cxx new file mode 100644 index 000000000..91ad73d19 --- /dev/null +++ b/idl/source/prj/svidl.cxx @@ -0,0 +1,215 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include +#include +#include +#include +#include +#include +#include +#include + +#define BR 0x8000 +static bool FileMove_Impl( const OUString & rFile1, const OUString & rFile2, bool bMoveAlways ) +{ + //printf( "Move from %s to %s\n", rFile2.GetStr(), rFile1.GetStr() ); + sal_uLong nC1 = 0; + sal_uLong nC2 = 1; + if( !bMoveAlways ) + { + SvFileStream aOutStm1( rFile1, StreamMode::STD_READ ); + SvFileStream aOutStm2( rFile2, StreamMode::STD_READ ); + if( aOutStm1.GetError() == ERRCODE_NONE ) + { + std::unique_ptr pBuf1(new sal_uInt8[ BR ]); + std::unique_ptr pBuf2(new sal_uInt8[ BR ]); + nC1 = aOutStm1.ReadBytes(pBuf1.get(), BR); + nC2 = aOutStm2.ReadBytes(pBuf2.get(), BR); + while( nC1 == nC2 ) + { + if( memcmp( pBuf1.get(), pBuf2.get(), nC1 ) ) + { + nC1++; + break; + } + else + { + if( 0x8000 != nC1 ) + break; + nC1 = aOutStm1.ReadBytes(pBuf1.get(), BR); + nC2 = aOutStm2.ReadBytes(pBuf2.get(), BR); + } + } + } + } + OUString fileURL2; + osl::FileBase::getFileURLFromSystemPath( rFile2, fileURL2 ); + if( nC1 != nC2 ) + {// something has changed + OUString fileURL1; + osl::FileBase::getFileURLFromSystemPath( rFile1, fileURL1 ); + // move file + if( osl::FileBase::E_None != osl::File::move( fileURL2, fileURL1 ) ) + { + // delete both files + osl::File::remove( fileURL1 ); + osl::File::remove( fileURL2 ); + return false; + } + return true; + } + return osl::FileBase::E_None == osl::File::remove( fileURL2 ); +} + +//This function gets a system path to a file [fname], creates a temp file in +//the same folder as [fname] and returns the system path of the temp file. +static OUString tempFileHelper(OUString const & fname) +{ + OUString aTmpFile; + + sal_Int32 delimIndex = fname.lastIndexOf( '/' ); + if( delimIndex > 0 ) + { + OUString aTmpDir( fname.copy( 0, delimIndex ) ); + osl::FileBase::getFileURLFromSystemPath( aTmpDir, aTmpDir ); + osl::FileBase::createTempFile( &aTmpDir, nullptr, &aTmpFile ); + osl::FileBase::getSystemPathFromFileURL( aTmpFile, aTmpFile ); + } + else + { + OString aStr = "invalid filename: " + + OUStringToOString(fname, RTL_TEXTENCODING_UTF8); + fprintf(stderr, "%s\n", aStr.getStr()); + } + return aTmpFile; +} + +int main ( int argc, char ** argv) +{ + OUString aTmpSlotMapFile; + OUString aTmpDepFile; + + SvCommand aCommand( argc, argv ); + + if( aCommand.nVerbosity != 0 ) + printf( "StarView Interface Definition Language (IDL) Compiler 3.0\n" ); + + Init(); + std::unique_ptr pDataBase( new SvIdlWorkingBase(aCommand)); + + int nExit = 0; + if( !aCommand.aExportFile.isEmpty() ) + { + osl::DirectoryItem aDI; + osl::FileStatus fileStatus( osl_FileStatus_Mask_FileName ); + (void)osl::DirectoryItem::get( aCommand.aExportFile, aDI ); + (void)aDI.getFileStatus(fileStatus); + pDataBase->SetExportFile( fileStatus.getFileName() ); + } + + if( ReadIdl( pDataBase.get(), aCommand ) ) + { + if( nExit == 0 && !aCommand.aSlotMapFile.isEmpty() ) + { + aTmpSlotMapFile = tempFileHelper(aCommand.aSlotMapFile); + SvFileStream aOutStm( aTmpSlotMapFile, StreamMode::READWRITE | StreamMode::TRUNC ); + if( !pDataBase->WriteSfx( aOutStm ) ) + { + nExit = -1; + OString aStr = "cannot write slotmap file: " + + OUStringToOString(aCommand.aSlotMapFile, RTL_TEXTENCODING_UTF8); + fprintf(stderr, "%s\n", aStr.getStr()); + } + } + if (nExit == 0 && !aCommand.m_DepFile.isEmpty()) + { + aTmpDepFile = tempFileHelper(aCommand.m_DepFile); + SvFileStream aOutStm( aTmpDepFile, StreamMode::READWRITE | StreamMode::TRUNC ); + pDataBase->WriteDepFile(aOutStm, aCommand.aTargetFile); + if( aOutStm.GetError() != ERRCODE_NONE ) + { + nExit = -1; + fprintf( stderr, "cannot write dependency file: %s\n", + OUStringToOString( aCommand.m_DepFile, + RTL_TEXTENCODING_UTF8 ).getStr() ); + } + } + } + else + nExit = -1; + + if( nExit == 0 ) + { + bool bErr = false; + bool bDoMove = aCommand.aTargetFile.isEmpty(); + OUString aErrFile, aErrFile2; + if (!aCommand.aSlotMapFile.isEmpty()) + { + bErr = !FileMove_Impl( aCommand.aSlotMapFile, aTmpSlotMapFile, bDoMove ); + if( bErr ) { + aErrFile = aCommand.aSlotMapFile; + aErrFile2 = aTmpSlotMapFile; + } + } + if (!bErr && !aCommand.m_DepFile.isEmpty()) + { + bErr |= !FileMove_Impl( aCommand.m_DepFile, aTmpDepFile, bDoMove ); + if (bErr) { + aErrFile = aCommand.m_DepFile; + aErrFile2 = aTmpDepFile; + } + } + + if( bErr ) + { + nExit = -1; + OString aStr = "cannot move file from: " + + OUStringToOString(aErrFile2, RTL_TEXTENCODING_UTF8) + + "\n to file: " + + OUStringToOString(aErrFile, RTL_TEXTENCODING_UTF8); + fprintf( stderr, "%s\n", aStr.getStr() ); + } + else + { + if( !aCommand.aTargetFile.isEmpty() ) + { + // stamp file, because idl passed through correctly + SvFileStream aOutStm( aCommand.aTargetFile, + StreamMode::READWRITE | StreamMode::TRUNC ); + } + } + } + + if( nExit != 0 ) + { + if( !aCommand.aSlotMapFile.isEmpty() ) + { + osl::FileBase::getSystemPathFromFileURL( aTmpSlotMapFile, aTmpSlotMapFile ); + osl::File::remove( aTmpSlotMapFile ); + } + } + + if( nExit != 0 ) + fprintf( stderr, "svidl terminated with errors\n" ); + return nExit; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit v1.2.3