summaryrefslogtreecommitdiffstats
path: root/idl
diff options
context:
space:
mode:
Diffstat (limited to 'idl')
-rw-r--r--idl/Executable_svidl.mk60
-rw-r--r--idl/IwyuFilter_idl.yaml2
-rw-r--r--idl/Makefile14
-rw-r--r--idl/Module_idl.mk26
-rw-r--r--idl/README.md9
-rw-r--r--idl/inc/basobj.hxx128
-rw-r--r--idl/inc/bastype.hxx76
-rw-r--r--idl/inc/command.hxx47
-rw-r--r--idl/inc/database.hxx141
-rw-r--r--idl/inc/globals.hxx128
-rw-r--r--idl/inc/hash.hxx61
-rw-r--r--idl/inc/lex.hxx217
-rw-r--r--idl/inc/module.hxx37
-rw-r--r--idl/inc/object.hxx90
-rw-r--r--idl/inc/parser.hxx72
-rw-r--r--idl/inc/slot.hxx134
-rw-r--r--idl/inc/types.hxx118
-rw-r--r--idl/source/cmptools/hash.cxx65
-rw-r--r--idl/source/cmptools/lex.cxx336
-rw-r--r--idl/source/objects/basobj.cxx141
-rw-r--r--idl/source/objects/bastype.cxx120
-rw-r--r--idl/source/objects/module.cxx34
-rw-r--r--idl/source/objects/object.cxx347
-rw-r--r--idl/source/objects/slot.cxx620
-rw-r--r--idl/source/objects/types.cxx320
-rw-r--r--idl/source/prj/command.cxx296
-rw-r--r--idl/source/prj/database.cxx553
-rw-r--r--idl/source/prj/globals.cxx84
-rw-r--r--idl/source/prj/parser.cxx590
-rw-r--r--idl/source/prj/svidl.cxx213
30 files changed, 5079 insertions, 0 deletions
diff --git a/idl/Executable_svidl.mk b/idl/Executable_svidl.mk
new file mode 100644
index 000000000..54676af66
--- /dev/null
+++ b/idl/Executable_svidl.mk
@@ -0,0 +1,60 @@
+# -*- 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_externals,svidl,\
+ dtoa \
+ zlib \
+))
+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,\
+ comphelper \
+ 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/IwyuFilter_idl.yaml b/idl/IwyuFilter_idl.yaml
new file mode 100644
index 000000000..ea0464ad3
--- /dev/null
+++ b/idl/IwyuFilter_idl.yaml
@@ -0,0 +1,2 @@
+---
+assumeFilename: idl/source/objects/object.cxx
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.md b/idl/README.md
new file mode 100644
index 000000000..019126c70
--- /dev/null
+++ b/idl/README.md
@@ -0,0 +1,9 @@
+# SvIDL Compiler
+
+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
+OpenOffice 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..2bdd8e622
--- /dev/null
+++ b/idl/inc/basobj.hxx
@@ -0,0 +1,128 @@
+/* -*- 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 <tools/ref.hxx>
+#include "bastype.hxx"
+#include <vector>
+
+class SvTokenStream;
+class SvIdlDataBase;
+
+template<typename T>
+class SvRefMemberList : private std::vector<T>
+{
+private:
+ typedef typename std::vector<T> 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<SvMetaReference> 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..7494b35a8
--- /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 <sal/types.h>
+#include <rtl/string.hxx>
+
+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 <rtl/ustring.hxx>
+#include <vector>
+
+class SvCommand
+{
+public:
+ std::vector<OUString> 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..dcdf93593
--- /dev/null
+++ b/idl/inc/database.hxx
@@ -0,0 +1,141 @@
+/* -*- 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 <rtl/string.hxx>
+
+#include <rtl/ustring.hxx>
+#include <set>
+#include <string_view>
+#include <exception>
+
+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<OUString> aIdFileList;
+ std::unique_ptr<SvStringHashTable> pIdTable;
+
+ SvRefMemberList<SvMetaType *> aTypeList;
+ SvRefMemberList<SvMetaClass *> aClassList;
+ SvRefMemberList<SvMetaModule *> aModuleList;
+ SvRefMemberList<SvMetaSlot *> aSlotList;
+ SvRefMemberList<SvMetaObject *> 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<SvMetaType *>& GetTypeList();
+ SvRefMemberList<SvMetaClass *>& GetClassList() { return aClassList; }
+ SvRefMemberList<SvMetaModule *>& GetModuleList() { return aModuleList; }
+
+ // list of used types while writing
+ SvRefMemberList<SvMetaType *> aUsedTypes;
+
+ void StartNewFile( std::u16string_view 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<SvMetaObject *>& 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_uInt32 * pVal );
+ void InsertId( const OString& rIdName, sal_uInt32 nVal );
+ bool ReadIdFile( std::string_view rFileName );
+
+ SvMetaType * FindType( std::string_view rName );
+ static SvMetaType * FindType( const SvMetaType *, SvRefMemberList<SvMetaType *>& );
+
+ SvMetaType * ReadKnownType( SvTokenStream & rInStm );
+ SvMetaAttribute * ReadKnownAttr( SvTokenStream & rInStm,
+ SvMetaType * pType );
+ SvMetaAttribute * FindKnownAttr( const SvIdentifier& );
+ SvMetaClass * ReadKnownClass( SvTokenStream & rInStm );
+ SvMetaClass * FindKnownClass( std::string_view aName );
+ void AddDepFile(OUString const& rFileName);
+ void WriteDepFile(SvFileStream & rStream, std::u16string_view 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..0739d8757
--- /dev/null
+++ b/idl/inc/globals.hxx
@@ -0,0 +1,128 @@
+/* -*- 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 <memory>
+
+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_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<SvStringHashTable> pHashTable;
+ std::unique_ptr<SvGlobalHashNames> 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(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..6bc904133
--- /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 <rtl/string.hxx>
+#include <tools/solar.h>
+#include <unordered_map>
+#include <memory>
+#include <utility>
+
+class SvStringHashEntry
+{
+ OString aName;
+ sal_uLong nValue;
+public:
+ SvStringHashEntry( OString aName_ )
+ : aName(std::move(aName_))
+ , 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<sal_uInt32, std::unique_ptr<SvStringHashEntry>> maInt2EntryMap;
+ std::unordered_map<OString, sal_uInt32> 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( std::string_view 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 <sal/types.h>
+#include "hash.hxx"
+#include <tools/stream.hxx>
+#include <vector>
+#include <memory>
+
+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<SvFileStream> pInStream;
+ OUString aFileName;
+ std::vector<std::unique_ptr<SvToken> > aTokList;
+ std::vector<std::unique_ptr<SvToken> >::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<std::unique_ptr<SvToken> >::iterator pRetToken = pCurToken;
+
+ // current iterator always valid
+ if(pCurToken != aTokList.begin())
+ --pCurToken;
+
+ return *(*pRetToken);
+ }
+
+ SvToken& GetToken_Next()
+ {
+ std::vector<std::unique_ptr<SvToken> >::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..08c14cc9c
--- /dev/null
+++ b/idl/inc/module.hxx
@@ -0,0 +1,37 @@
+/* -*- 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 "object.hxx"
+
+class SvMetaModule final : public SvMetaObject
+{
+public:
+ SvRefMemberList<SvMetaClass *> 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..8d16ca563
--- /dev/null
+++ b/idl/inc/object.hxx
@@ -0,0 +1,90 @@
+/* -*- 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 <tools/solar.h>
+
+#include <vector>
+
+class SvMetaClass;
+typedef ::std::vector< SvMetaClass* > SvMetaClassList;
+
+class SvClassElement
+{
+ OString aPrefix;
+ tools::SvRef<SvMetaClass> 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<SvMetaClass> aSuperClass;
+ std::vector<SvClassElement> aClassElementList;
+ SvRefMemberList<SvMetaAttribute *> aAttrList;
+ bool TestAttribute( SvIdlDataBase & rBase, SvTokenStream & rInStm,
+ SvMetaAttribute & rAttr ) const;
+private:
+
+ static void WriteSlotStubs( std::string_view rShellName,
+ SvSlotElementList & rSlotList,
+ std::vector<OString> & rList,
+ SvStream & rOutStm );
+ static sal_uInt16 WriteSlotParamArray( SvIdlDataBase & rBase,
+ SvSlotElementList & rSlotList,
+ SvStream & rOutStm );
+ static sal_uInt16 WriteSlots( std::string_view rShellName,
+ SvSlotElementList & rSlotList,
+ SvIdlDataBase & rBase,
+ SvStream & rOutStm );
+
+ void InsertSlots( SvSlotElementList& rList, std::vector<sal_uLong>& 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 <rtl/ustring.hxx>
+#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..f8ba61d98
--- /dev/null
+++ b/idl/inc/slot.hxx
@@ -0,0 +1,134 @@
+/* -*- 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 <tools/solar.h>
+
+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;
+
+ void WriteSlot( std::string_view rShellName,
+ sal_uInt16 nCount, std::string_view 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;
+
+ 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( std::string_view rShellName,
+ std::vector<OString> & rList,
+ SvStream & rOutStm ) const;
+ sal_uInt16 WriteSlotMap( std::string_view 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..badab618e
--- /dev/null
+++ b/idl/inc/types.hxx
@@ -0,0 +1,118 @@
+/* -*- 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 <rtl/strbuf.hxx>
+#include <tools/ref.hxx>
+#include "basobj.hxx"
+
+class SvMetaType;
+class SvMetaSlot;
+typedef SvRefMemberList< SvMetaSlot* > SvSlotElementList;
+
+class SvMetaAttribute : public SvMetaReference
+{
+public:
+ tools::SvRef<SvMetaType> 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;
+ size_t MakeSfx( OStringBuffer& rAtrrArray ) const;
+ virtual void Insert( SvSlotElementList& );
+};
+
+enum MetaTypeType { Method, Struct, Base, Enum, Interface, Shell };
+
+class SvMetaType : public SvMetaReference
+{
+ SvRefMemberList<SvMetaAttribute *> aAttrList;
+ MetaTypeType nType;
+ bool bIsItem;
+
+ void WriteSfxItem( std::string_view 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<SvMetaAttribute *>&
+ GetAttrList() { return aAttrList; }
+ size_t 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;
+
+ size_t 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<SvMetaEnumValue *> 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..d3993881a
--- /dev/null
+++ b/idl/source/cmptools/hash.cxx
@@ -0,0 +1,65 @@
+/* -*- 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 .
+ */
+
+
+// program-sensitive includes
+#include <hash.hxx>
+
+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<SvStringHashEntry>(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( std::string_view 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 <memory>
+#include <hash.hxx>
+#include <lex.hxx>
+#include <globals.hxx>
+#include <rtl/strbuf.hxx>
+#include<rtl/character.hxx>
+
+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<SvToken>(pToken));
+ do
+ {
+ if( !MakeToken( *pToken ) )
+ {
+ if (!aTokList.empty())
+ {
+ *pToken = SvToken();
+ std::vector<std::unique_ptr<SvToken> >::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<SvToken>(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<unsigned char>(c) ) )
+ {
+ if( rtl::isAsciiDigit( static_cast<unsigned char>(c) ) )
+ l = l * nLog + (c - '0');
+ else
+ l = l * nLog
+ + (rtl::toAsciiUpperCase( static_cast<unsigned char>(c) )
+ - 'A' + 10 );
+ c = GetFastNextChar();
+ }
+ }
+ else
+ {
+ while( rtl::isAsciiDigit( static_cast<unsigned char>(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<unsigned char>(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<unsigned char>(c) ) )
+ {
+ rToken.nType = SVTOKENTYPE::Integer;
+ rToken.nLong = GetNumber();
+
+ }
+ else if( rtl::isAsciiAlpha (static_cast<unsigned char>(c)) || (c == '_') )
+ {
+ OStringBuffer aBuf(64);
+ while( rtl::isAsciiAlphanumeric( static_cast<unsigned char>(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..872b42b39
--- /dev/null
+++ b/idl/source/objects/basobj.cxx
@@ -0,0 +1,141 @@
+/* -*- 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 <sal/config.h>
+
+#include <rtl/character.hxx>
+
+#include <basobj.hxx>
+#include <database.hxx>
+
+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_uInt64 nPos = rOutStm.Tell();
+ rOutStm.SeekRel( -1 );
+ char c = 0;
+ rOutStm.ReadChar( c );
+
+ while( rtl::isAsciiWhiteSpace( static_cast<unsigned char>(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..6a36db617
--- /dev/null
+++ b/idl/source/objects/bastype.cxx
@@ -0,0 +1,120 @@
+/* -*- 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 <bastype.hxx>
+#include <lex.hxx>
+#include <hash.hxx>
+#include <database.hxx>
+
+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_uInt32 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..dc692f608
--- /dev/null
+++ b/idl/source/objects/module.cxx
@@ -0,0 +1,34 @@
+/* -*- 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 <module.hxx>
+#include <database.hxx>
+
+SvMetaModule::SvMetaModule() {}
+
+void SvMetaModule::WriteSfx(SvIdlDataBase& rBase, SvStream& rOutStm)
+{
+ for (size_t 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..510d3a8a7
--- /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 <sal/config.h>
+
+#include <algorithm>
+
+#include <rtl/strbuf.hxx>
+#include <sal/log.hxx>
+
+#include <object.hxx>
+#include <globals.hxx>
+#include <database.hxx>
+#include <slot.hxx>
+
+
+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<SvMetaAttribute> 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<const SvMetaSlot *>(&rAttr) )
+ {
+ SAL_WARN( "idl", "new slot : " << rAttr.GetSlotId().getString() );
+ }
+
+ for( size_t 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( std::string_view 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<sal_uLong>& 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<sal_uLong>::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( std::string_view rShellName,
+ SvSlotElementList & rSlotList,
+ std::vector<OString> & 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<sal_uLong> 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<OString> 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..17b8970ed
--- /dev/null
+++ b/idl/source/objects/slot.cxx
@@ -0,0 +1,620 @@
+/* -*- 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 <osl/diagnose.h>
+#include <tools/debug.hxx>
+#include <slot.hxx>
+#include <globals.hxx>
+#include <database.hxx>
+
+
+SvMetaSlot::SvMetaSlot()
+ : aRecordPerSet( true )
+ , aRecordAbsolute( false )
+ , pNextSlot(nullptr)
+ , nListPos(0)
+ , aReadOnlyDoc ( true )
+{
+}
+
+SvMetaSlot::SvMetaSlot( SvMetaType * pType )
+ : SvMetaAttribute( pType )
+ , aRecordPerSet( true )
+ , aRecordAbsolute( false )
+ , pNextSlot(nullptr)
+ , nListPos(0)
+ , aReadOnlyDoc ( true )
+{
+}
+
+bool SvMetaSlot::GetReadOnlyDoc() const
+{
+ if( aReadOnlyDoc.IsSet() || !GetRef() ) return aReadOnlyDoc;
+ return static_cast<SvMetaSlot *>(GetRef())->GetReadOnlyDoc();
+}
+
+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<SvMetaSlot *>(GetRef())->GetGroupId();
+}
+const OString& SvMetaSlot::GetDisableFlags() const
+{
+ if( !aDisableFlags.isEmpty() || !GetRef() ) return aDisableFlags;
+ return static_cast<SvMetaSlot *>(GetRef())->GetDisableFlags();
+}
+const OString& SvMetaSlot::GetExecMethod() const
+{
+ if( !aExecMethod.getString().isEmpty() || !GetRef() ) return aExecMethod.getString();
+ return static_cast<SvMetaSlot *>(GetRef())->GetExecMethod();
+}
+const OString& SvMetaSlot::GetStateMethod() const
+{
+ if( !aStateMethod.getString().isEmpty() || !GetRef() ) return aStateMethod.getString();
+ return static_cast<SvMetaSlot *>(GetRef())->GetStateMethod();
+}
+bool SvMetaSlot::GetToggle() const
+{
+ if( aToggle.IsSet() || !GetRef() ) return aToggle;
+ return static_cast<SvMetaSlot *>(GetRef())->GetToggle();
+}
+bool SvMetaSlot::GetAutoUpdate() const
+{
+ if( aAutoUpdate.IsSet() || !GetRef() ) return aAutoUpdate;
+ return static_cast<SvMetaSlot *>(GetRef())->GetAutoUpdate();
+}
+bool SvMetaSlot::GetAsynchron() const
+{
+ // Synchron and Asynchron are exclusive
+ if( !GetRef() || aAsynchron.IsSet() )
+ return aAsynchron;
+ return static_cast<SvMetaSlot *>(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<SvMetaSlot *>(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<SvMetaSlot *>(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<SvMetaSlot *>(GetRef())->GetNoRecord();
+}
+bool SvMetaSlot::GetRecordAbsolute() const
+{
+ if( !GetRef() || aRecordAbsolute.IsSet() )
+ return aRecordAbsolute;
+ return static_cast<SvMetaSlot *>(GetRef())->GetRecordAbsolute();
+}
+bool SvMetaSlot::GetMenuConfig() const
+{
+ if( aMenuConfig.IsSet() || !GetRef() ) return aMenuConfig;
+ return static_cast<SvMetaSlot *>(GetRef())->GetMenuConfig();
+}
+bool SvMetaSlot::GetToolBoxConfig() const
+{
+ if( aToolBoxConfig.IsSet() || !GetRef() ) return aToolBoxConfig;
+ return static_cast<SvMetaSlot *>(GetRef())->GetToolBoxConfig();
+}
+bool SvMetaSlot::GetAccelConfig() const
+{
+ if( aAccelConfig.IsSet() || !GetRef() ) return aAccelConfig;
+ return static_cast<SvMetaSlot *>(GetRef())->GetAccelConfig();
+}
+bool SvMetaSlot::GetFastCall() const
+{
+ if( aFastCall.IsSet() || !GetRef() ) return aFastCall;
+ return static_cast<SvMetaSlot *>(GetRef())->GetFastCall();
+}
+bool SvMetaSlot::GetContainer() const
+{
+ if( aContainer.IsSet() || !GetRef() ) return aContainer;
+ return static_cast<SvMetaSlot *>(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 );
+ 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<SvMetaSlot*>( 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<SvMetaSlot*>( 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<sal_uInt16>(GetSlotId().GetValue());
+ sal_uInt16 nListCount = static_cast<sal_uInt16>(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<int>(nId) - static_cast<int>(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<sal_uInt16>(rList[ nPos ]->GetSlotId().GetValue()),
+ "Successor has lower SlotId" );
+ DBG_ASSERT( nPos == 0 || nId >
+ static_cast<sal_uInt16>(rList[ nPos-1 ]->GetSlotId().GetValue()),
+ "Predecessor has higher SlotId" );
+ DBG_ASSERT( nPos+1 >= nListCount || nId <
+ static_cast<sal_uInt16>(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( std::string_view rShellName,
+ std::vector<OString> & rList,
+ SvStream & rOutStm ) const
+{
+ 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( std::string_view rShellName, sal_uInt16 nCount,
+ std::string_view rSlotId,
+ SvSlotElementList& rSlotList,
+ size_t nStart,
+ SvIdlDataBase & rBase, SvStream & rOutStm )
+{
+ 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( !IsMethod() )
+ return 0;
+
+ SvMetaType * pType = GetType();
+
+ if( !SvIdlDataBase::FindType( pType, rBase.aUsedTypes ) )
+ rBase.aUsedTypes.push_back( pType );
+
+ const SvRefMemberList<SvMetaAttribute *>& rList =
+ pType->GetAttrList();
+ for( size_t 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<sal_uInt16>(rList.size());
+}
+
+sal_uInt16 SvMetaSlot::WriteSlotMap( std::string_view 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<sal_uInt16>(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..08492b4b6
--- /dev/null
+++ b/idl/source/objects/types.cxx
@@ -0,0 +1,320 @@
+/* -*- 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 <sal/config.h>
+
+#include <algorithm>
+
+#include <tools/debug.hxx>
+
+#include <types.hxx>
+#include <globals.hxx>
+#include <database.hxx>
+
+SvMetaAttribute::SvMetaAttribute()
+{
+}
+
+SvMetaAttribute::SvMetaAttribute( SvMetaType * pType )
+ : aType( pType )
+{
+}
+
+SvMetaType * SvMetaAttribute::GetType() const
+{
+ if( aType.is() || !GetRef() ) return aType.get();
+ return static_cast<SvMetaAttribute *>(GetRef())->GetType();
+}
+
+const SvIdentifier & SvMetaAttribute::GetSlotId() const
+{
+ if( aSlotId.IsSet() || !GetRef() ) return aSlotId;
+ return static_cast<SvMetaAttribute *>(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<SvMetaType> 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;
+}
+
+size_t 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&)
+{
+}
+
+SvMetaType::SvMetaType()
+ : nType( MetaTypeType::Base )
+ , bIsItem( false )
+{
+}
+
+SvMetaType::SvMetaType( const OString& rName )
+ : SvMetaType()
+{
+ SetName( rName );
+}
+
+SvMetaType::~SvMetaType()
+{}
+
+void SvMetaType::SetType( MetaTypeType nT )
+{
+ nType = nT;
+}
+
+SvMetaType * SvMetaType::GetBaseType() const
+{
+ if( GetRef() && GetMetaTypeType() == MetaTypeType::Base )
+ return static_cast<SvMetaType *>(GetRef())->GetBaseType();
+ return const_cast<SvMetaType *>(this);
+}
+
+SvMetaType * SvMetaType::GetReturnType() const
+{
+ DBG_ASSERT( GetMetaTypeType() == MetaTypeType::Method, "no method" );
+ DBG_ASSERT( GetRef(), "no return type" );
+ return static_cast<SvMetaType *>(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<SvMetaAttribute> xAttr( new SvMetaAttribute() );
+ if( xAttr->ReadSvIdl( rBase, rInStm ) )
+ {
+ if( xAttr->Test( rInStm ) )
+ GetAttrList().push_back( xAttr.get() );
+ }
+}
+
+size_t SvMetaType::MakeSfx( OStringBuffer& rAttrArray )
+{
+ size_t nC = 0;
+
+ if( GetBaseType()->GetMetaTypeType() == MetaTypeType::Struct )
+ {
+ size_t nAttrCount = GetAttrCount();
+ // write the single attributes
+ for( size_t n = 0; n < nAttrCount; n++ )
+ {
+ nC += aAttrList[n]->MakeSfx( rAttrArray );
+ if( n +1 < nAttrCount )
+ rAttrArray.append(", ");
+ }
+ }
+ return nC;
+}
+
+void SvMetaType::WriteSfxItem(
+ std::string_view rItemName, SvIdlDataBase const & rBase, SvStream& rOutStm )
+{
+ WriteStars( rOutStm );
+ OString aVarName = OString::Concat(" a") + rItemName + "_Impl";
+
+ OStringBuffer aAttrArray(1024);
+ size_t 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 == "SfxInt16Item" ||
+ 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(EMSCRIPTEN) || 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..0c9436ce3
--- /dev/null
+++ b/idl/source/prj/command.cxx
@@ -0,0 +1,296 @@
+/* -*- 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 <sal/config.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <osl/diagnose.h>
+#include <rtl/character.hxx>
+
+#include <command.hxx>
+#include <globals.hxx>
+#include <database.hxx>
+#include <parser.hxx>
+
+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-args:",
+"\t( { item parameter-name SLOT_ID } )\n",
+
+"\tslot definition:",
+"\titem identifier SLOT_ID [ item-method-args ]",
+"\t'['",
+"\t\tAccelConfig, MenuConfig, ToolbarConfig",
+"\t\tAutoUpdate",
+"\t\tContainer",
+"\t\tExecMethod = Identifier",
+"\t\tFastCall",
+"\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<slotmap file>\n"
+"-fm<makefile target file>\n"
+"-help, ? @<file> response file\n"
+" <filenames>\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<OUString> * 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;
+
+ OStringBuffer aStr;
+ while( aStm.ReadLine( aStr ) )
+ {
+ sal_uInt16 n = 0;
+ sal_uInt16 nPos = 1;
+ while( n != nPos )
+ {
+ while( aStr[n]
+ && rtl::isAsciiWhiteSpace(
+ static_cast<unsigned char>(aStr[n]) ) )
+ n++;
+ nPos = n;
+ while( aStr[n]
+ && !rtl::isAsciiWhiteSpace(
+ static_cast<unsigned char>(aStr[n]) ) )
+ n++;
+ if( n != nPos )
+ pList->push_back( OStringToOUString(std::string_view(aStr).substr(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<OUString> 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();
+
+ auto const env = getenv("INCLUDE");
+ OString aInc(env == nullptr ? "" : env);
+ // 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..9aba715ed
--- /dev/null
+++ b/idl/source/prj/database.cxx
@@ -0,0 +1,553 @@
+/* -*- 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 <sal/config.h>
+
+#include <algorithm>
+#include <stdio.h>
+#include <string_view>
+
+#include <command.hxx>
+#include <database.hxx>
+#include <globals.hxx>
+#include <slot.hxx>
+#include <rtl/strbuf.hxx>
+#include <osl/file.hxx>
+
+
+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<SvMetaType *>& 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_uInt32 * 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_uInt32 nVal )
+{
+ if( !pIdTable )
+ pIdTable.reset( new SvStringHashTable );
+
+ sal_uInt32 nHash;
+ pIdTable->Insert( rIdName, &nHash )->SetValue( nVal );
+}
+
+bool SvIdlDataBase::ReadIdFile( std::string_view 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_uInt32 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.IsChar() && rTok.GetChar() == ':')
+ {
+ // add support for "::avmedia::MediaItem" namespaced identifier
+ rTok = aTokStm.GetToken_Next();
+ if( !rTok.IsChar() || rTok.GetChar() != ':')
+ throw SvParseException( "expected ':'", rTok );
+ // the lexer reads "avmedia::MediaItem" as an identifier
+ rTok = aTokStm.GetToken_Next();
+ if( !rTok.IsIdentifier() )
+ throw SvParseException( "expected identifier", rTok );
+ }
+ else 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_uInt32 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<SvMetaType *>& rList )
+{
+ for (auto const& elem : rList)
+ if( elem == pPType )
+ return elem;
+ return nullptr;
+}
+
+SvMetaType * SvIdlDataBase::FindType( std::string_view 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_uInt32 n;
+ if( FindId( rTok.GetString(), &n ) )
+ {
+ for( size_t i = 0; i < aSlotList.size(); i++ )
+ {
+ SvMetaSlot * pSlot = aSlotList[i];
+ if( pSlot->GetSlotId().getString() == rTok.GetString() )
+ return pSlot;
+ }
+ }
+
+ OSL_FAIL(OString("Not found : " + rTok.GetString()).getStr());
+ }
+ }
+
+ rInStm.Seek( nTokPos );
+ return nullptr;
+}
+
+SvMetaAttribute* SvIdlDataBase::FindKnownAttr( const SvIdentifier& rId )
+{
+ sal_uInt32 n;
+ if( FindId( rId.getString(), &n ) )
+ {
+ for( size_t 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( std::string_view aName )
+{
+ for( size_t 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_uInt64 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<sal_Int64>(aError.nLine));
+ aErrorText.append(", ");
+ aErrorText.append(static_cast<sal_Int64>(aError.nColumn));
+ aErrorText.append(" )");
+
+ // reset error
+ aError = SvIdlError();
+ }
+
+ // error treatment
+ fprintf( stderr, "\n%s --- %s: ( %" SAL_PRIuUINT64 ", %" SAL_PRIuUINT64 " )\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 );
+ size_t 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( std::u16string_view 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() (std::u16string_view 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() (std::u16string_view rItem)
+ {
+ m_rStream.WriteOString( OUStringToOString(rItem, RTL_TEXTENCODING_UTF8) );
+ m_rStream.WriteCharPtr( " :\n\n" );
+ }
+};
+
+}
+
+void SvIdlDataBase::WriteDepFile(
+ SvFileStream & rStream, std::u16string_view 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..cf8d2ad44
--- /dev/null
+++ b/idl/source/prj/globals.cxx
@@ -0,0 +1,84 @@
+/* -*- 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 <sal/config.h>
+
+#include <globals.hxx>
+
+IdlDll & GetIdlApp()
+{
+ static IdlDll aIdlDll;
+ return aIdlDll;
+}
+
+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(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..31bbee9a9
--- /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 <sal/config.h>
+
+#include <algorithm>
+
+#include <parser.hxx>
+#include <database.hxx>
+#include <globals.hxx>
+#include <slot.hxx>
+#include <osl/file.hxx>
+
+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<SvMetaModule> 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<SvMetaSlot> 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<SvMetaType> xStruct(new SvMetaType() );
+ xStruct->SetType( MetaTypeType::Struct );
+ xStruct->SetName( ReadIdentifier() );
+ Read( '{' );
+ while( true )
+ {
+ tools::SvRef<SvMetaAttribute> xAttr( new SvMetaAttribute() );
+ xAttr->aType = ReadKnownType();
+ xAttr->SetName(ReadIdentifier());
+ xAttr->aSlotId.setString(ReadIdentifier());
+ sal_uInt32 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<SvMetaType> 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<SvMetaTypeEnum> 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 std::string_view getCommonSubPrefix(std::string_view rA, std::string_view rB)
+{
+ sal_Int32 nMax = std::min(rA.size(), rB.size());
+ sal_Int32 nI = 0;
+ while (nI < nMax)
+ {
+ if (rA[nI] != rB[nI])
+ break;
+ ++nI;
+ }
+ return rA.substr(0, nI);
+}
+
+void SvIdlParser::ReadEnumValue( SvMetaTypeEnum& rEnum )
+{
+ tools::SvRef<SvMetaEnumValue> aEnumVal = new SvMetaEnumValue();
+ aEnumVal->SetName( ReadIdentifier() );
+ if( rEnum.aEnumValueList.empty() )
+ {
+ // the first
+ rEnum.aPrefix = aEnumVal->GetName();
+ }
+ else
+ {
+ rEnum.aPrefix = OString(getCommonSubPrefix(rEnum.aPrefix, aEnumVal->GetName()));
+ }
+ rEnum.aEnumValueList.push_back( aEnumVal.get() );
+}
+
+void SvIdlParser::ReadInterfaceOrShell( SvMetaModule& rModule, MetaTypeType aMetaTypeType )
+{
+ tools::SvRef<SvMetaClass> 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<SvMetaAttribute> xAttr;
+ bool bOk = false;
+ if( !pType || pType->IsItem() )
+ {
+ xAttr = new SvMetaSlot( pType );
+ bOk = ReadSlot(static_cast<SvMetaSlot&>(*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<SvMetaSlot*>( 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<SvMetaSlot*>( 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.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<SvMetaType> xT(new SvMetaType() );
+ xT->SetRef(rAttr.GetType() );
+ rAttr.aType = xT;
+ rAttr.aType->SetType( MetaTypeType::Method );
+ if (ReadIf(')'))
+ return;
+
+ while (true)
+ {
+ tools::SvRef<SvMetaAttribute> 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_uInt32 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..2c9fbf63d
--- /dev/null
+++ b/idl/source/prj/svidl.cxx
@@ -0,0 +1,213 @@
+/* -*- 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 <stdio.h>
+#include <database.hxx>
+#include <command.hxx>
+#include <rtl/ustring.hxx>
+#include <osl/file.hxx>
+#include <memory>
+
+#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<sal_uInt8[]> pBuf1(new sal_uInt8[ BR ]);
+ std::unique_ptr<sal_uInt8[]> 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(std::u16string_view fname)
+{
+ OUString aTmpFile;
+
+ size_t delimIndex = fname.rfind( '/' );
+ if( delimIndex > 0 && delimIndex != std::u16string_view::npos)
+ {
+ OUString aTmpDir( fname.substr( 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<SvIdlWorkingBase> 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: */