summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephan Bergmann <stephan.bergmann@allotropia.de>2024-01-25 16:59:49 +0100
committerStephan Bergmann <stephan.bergmann@allotropia.de>2024-01-25 18:31:42 +0100
commitcbae6e581ad62771122d35742bd304be44fb982c (patch)
tree1d08888c821eb2de19033cd0925c73e5faad47fb
parentc479944eb4f9f5a22c7b248185f22c86ea85d12a (diff)
Let embindmaker also generate a .js file with more natural names
(i.e., Module.unoembind_uno.com.sun.star... vs. Module.com$sun$star$..., and see the updated examples in static/README.wasm.md for further shortening that to just css...) Change-Id: I6dc079caa8c93a4042a6a8aa2d8fcc8f76bf80f3 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162580 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
-rw-r--r--Repository.mk1
-rw-r--r--static/CustomTarget_unoembind.mk10
-rw-r--r--static/Module_static.mk1
-rw-r--r--static/Package_unoembind.mk18
-rw-r--r--static/README.wasm.md18
-rw-r--r--static/source/embindmaker/embindmaker.cxx335
6 files changed, 260 insertions, 123 deletions
diff --git a/Repository.mk b/Repository.mk
index 2eb8ae6936e8..f39f9dc656df 100644
--- a/Repository.mk
+++ b/Repository.mk
@@ -1036,6 +1036,7 @@ $(eval $(call gb_Helper_register_packages_for_install,ooo,\
) \
resource_fonts \
cui \
+ $(if $(filter EMSCRIPTEN,$(OS)),unoembind) \
))
$(eval $(call gb_Helper_register_packages_for_install,ooo_fonts,\
diff --git a/static/CustomTarget_unoembind.mk b/static/CustomTarget_unoembind.mk
index 4bed6f585fa7..cccb36f1dce2 100644
--- a/static/CustomTarget_unoembind.mk
+++ b/static/CustomTarget_unoembind.mk
@@ -11,12 +11,16 @@ $(eval $(call gb_CustomTarget_CustomTarget,static/unoembind))
$(eval $(call gb_CustomTarget_register_targets,static/unoembind, \
bindings_uno.cxx \
+ bindings_uno.js \
))
-$(call gb_CustomTarget_get_workdir,static/unoembind)/bindings_uno.cxx: \
+$(call gb_CustomTarget_get_workdir,static/unoembind)/bindings_uno.cxx \
+$(call gb_CustomTarget_get_workdir,static/unoembind)/bindings_uno.js: \
$(call gb_Executable_get_target_for_build,embindmaker) $(call gb_UnoApi_get_target,udkapi) \
$(call gb_UnoApi_get_target,offapi)
- $(call gb_Executable_get_command,embindmaker) uno +$(call gb_UnoApi_get_target,udkapi) \
- +$(call gb_UnoApi_get_target,offapi) > $@
+ $(call gb_Executable_get_command,embindmaker) uno \
+ $(call gb_CustomTarget_get_workdir,static/unoembind)/bindings_uno.cxx \
+ $(call gb_CustomTarget_get_workdir,static/unoembind)/bindings_uno.js \
+ +$(call gb_UnoApi_get_target,udkapi) +$(call gb_UnoApi_get_target,offapi)
# vim: set noet sw=4 ts=4:
diff --git a/static/Module_static.mk b/static/Module_static.mk
index 3b785c7ba4cb..c91441a6b924 100644
--- a/static/Module_static.mk
+++ b/static/Module_static.mk
@@ -19,6 +19,7 @@ ifeq (EMSCRIPTEN,$(OS))
$(eval $(call gb_Module_add_targets,static,\
CustomTarget_emscripten_fs_image \
CustomTarget_unoembind \
+ Package_unoembind \
StaticLibrary_unoembind \
$(if $(ENABLE_QT5), \
CustomTarget_wasm-qt5-mandelbrot_moc \
diff --git a/static/Package_unoembind.mk b/static/Package_unoembind.mk
new file mode 100644
index 000000000000..d1f82b970424
--- /dev/null
+++ b/static/Package_unoembind.mk
@@ -0,0 +1,18 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t; fill-column: 100 -*-
+#
+# 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/.
+#
+
+$(eval $(call gb_Package_Package,unoembind,$(call gb_CustomTarget_get_workdir,static/unoembind)))
+
+$(eval $(call gb_Package_use_custom_target,unoembind,static/unoembind))
+
+$(eval $(call gb_Package_add_files,unoembind,$(LIBO_BIN_FOLDER), \
+ bindings_uno.js \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/static/README.wasm.md b/static/README.wasm.md
index f39a79247d00..2bfecb404a7e 100644
--- a/static/README.wasm.md
+++ b/static/README.wasm.md
@@ -223,29 +223,33 @@ improvement! ;)
Some usage examples through javascript of the current implementation:
```js
// inserts a string at the start of the Writer document.
+Module.init_unoembind_uno();
+let css = Module.unoembind_uno.com.sun.star;
xModel = Module.getCurrentModelFromViewSh();
-xTextDocument = new Module.com$sun$star$text$XTextDocumentRef(xModel, Module.UnoReference_Query.UNO_QUERY);
+xTextDocument = new css.text.XTextDocument(xModel, Module.UnoReference_Query.UNO_QUERY);
xText = xTextDocument.getText();
-xSimpleText = new Module.com$sun$star$text$XSimpleTextRef(xText, Module.UnoReference_Query.UNO_QUERY);
+xSimpleText = new css.text.XSimpleText(xText, Module.UnoReference_Query.UNO_QUERY);
xTextCursor = xSimpleText.createTextCursor();
-xTextRange = new Module.com$sun$star$text$XTextRangeRef(xTextCursor, Module.UnoReference_Query.UNO_QUERY);
+xTextRange = new css.text.XTextRange(xTextCursor, Module.UnoReference_Query.UNO_QUERY);
xTextRange.setString(new Module.OUString("string here!"));
xModel.delete(); xTextDocument.delete(); xText.delete(); xSimpleText.delete(); xTextCursor.delete(); xTextRange.delete();
```
```js
// changes each paragraph of the Writer document to a random color.
+Module.init_unoembind_uno();
+let css = Module.unoembind_uno.com.sun.star;
xModel = Module.getCurrentModelFromViewSh();
-xTextDocument = new Module.com$sun$star$text$XTextDocumentRef(xModel, Module.UnoReference_Query.UNO_QUERY);
+xTextDocument = new css.text.XTextDocument(xModel, Module.UnoReference_Query.UNO_QUERY);
xText = xTextDocument.getText();
-xEnumAccess = new Module.com$sun$star$container$XEnumerationAccessRef(xText, Module.UnoReference_Query.UNO_QUERY);
+xEnumAccess = new css.container.XEnumerationAccess(xText, Module.UnoReference_Query.UNO_QUERY);
xParaEnumeration = xEnumAccess.createEnumeration();
while (xParaEnumeration.hasMoreElements()) {
- xParagraph = new Module.com$sun$star$text$XTextRangeRef();
+ xParagraph = new css.text.XTextRange();
xParagraph.set(xParaEnumeration.nextElement(), Module.UnoReference_Query.UNO_QUERY);
if (xParagraph.is()) {
- xParaProps = new Module.com$sun$star$beans$XPropertySetRef(xParagraph, Module.UnoReference_Query.UNO_QUERY);
+ xParaProps = new css.beans.XPropertySet(xParagraph, Module.UnoReference_Query.UNO_QUERY);
xParaProps.setPropertyValue(new Module.OUString("CharColor"), new Module.Any(Math.floor(Math.random() * 0xFFFFFF), Module.UnoType.long));
}
}
diff --git a/static/source/embindmaker/embindmaker.cxx b/static/source/embindmaker/embindmaker.cxx
index 184d635da5c0..ed326ce4ed99 100644
--- a/static/source/embindmaker/embindmaker.cxx
+++ b/static/source/embindmaker/embindmaker.cxx
@@ -11,7 +11,13 @@
#include <cassert>
#include <cstdlib>
+#include <fstream>
+#include <ios>
#include <iostream>
+#include <map>
+#include <memory>
+#include <ostream>
+#include <string>
#include <string_view>
#include <utility>
#include <vector>
@@ -20,9 +26,11 @@
#include <codemaker/typemanager.hxx>
#include <osl/file.hxx>
#include <osl/process.h>
+#include <osl/thread.h>
#include <rtl/process.h>
#include <rtl/ref.hxx>
#include <rtl/string.hxx>
+#include <rtl/textcvt.h>
#include <rtl/ustrbuf.hxx>
#include <rtl/ustring.hxx>
#include <sal/main.h>
@@ -35,14 +43,32 @@ void badUsage()
{
std::cerr
<< "Usage:\n\n"
- " embindmaker <prefix> <registries>\n\n"
+ " embindmaker <name> <cpp-ouptput> <js-output> <registries>\n\n"
"where each <registry> is '+' (primary) or ':' (secondary), followed by: either a\n"
"new- or legacy-format .rdb file, a single .idl file, or a root directory of an\n"
- ".idl file tree. Embind code for all primary registries is written to stdout,"
- "with <prefix> used as part of the name passed to EMSCRIPTEN_BINDINGS.\n";
+ ".idl file tree. For all primary registries, Embind code is written to\n"
+ "<cpp-output> and corresponding JavaScript scaffolding code is written to\n"
+ "<js-output>. The <name> is used as part of some of the identifiers in those\n"
+ "generated files.\n";
std::exit(EXIT_FAILURE);
}
+std::string getPathnameArgument(sal_uInt32 argument)
+{
+ OUString arg;
+ rtl_getAppCommandArg(argument, &arg.pData);
+ OString path;
+ auto const enc = osl_getThreadTextEncoding();
+ if (!arg.convertToString(&path, enc,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
+ | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR))
+ {
+ std::cerr << "Cannot convert \"" << arg << "\" to system encoding " << enc << "\n";
+ std::exit(EXIT_FAILURE);
+ }
+ return std::string(path);
+}
+
std::pair<OUString, bool> parseRegistryArgument(sal_uInt32 argument)
{
OUString arg;
@@ -86,10 +112,17 @@ std::pair<OUString, bool> parseRegistryArgument(sal_uInt32 argument)
return { abs, primary };
}
+struct Module
+{
+ std::map<OUString, std::shared_ptr<Module>> modules;
+ std::vector<OUString> interfaces;
+};
+
void scan(rtl::Reference<unoidl::MapCursor> const& cursor, std::u16string_view prefix,
- std::vector<OUString>& interfaces)
+ Module* module, std::vector<OUString>& interfaces)
{
assert(cursor.is());
+ assert(module != nullptr);
for (;;)
{
OUString id;
@@ -102,10 +135,18 @@ void scan(rtl::Reference<unoidl::MapCursor> const& cursor, std::u16string_view p
switch (ent->getSort())
{
case unoidl::Entity::SORT_MODULE:
+ {
+ auto& sub = module->modules[id];
+ if (!sub)
+ {
+ sub = std::make_shared<Module>();
+ }
scan(static_cast<unoidl::ModuleEntity*>(ent.get())->createCursor(),
- Concat2View(name + "."), interfaces);
+ Concat2View(name + "."), sub.get(), interfaces);
break;
+ }
case unoidl::Entity::SORT_INTERFACE_TYPE:
+ module->interfaces.emplace_back(name);
interfaces.emplace_back(name);
break;
default:
@@ -118,16 +159,17 @@ OUString cppName(OUString const& name) { return "::" + name.replaceAll(u".", u":
OUString jsName(OUString const& name) { return name.replace('.', '$'); }
-void dumpAttributes(OUString const& name, rtl::Reference<unoidl::InterfaceTypeEntity> const& entity)
+void dumpAttributes(std::ostream& out, OUString const& name,
+ rtl::Reference<unoidl::InterfaceTypeEntity> const& entity)
{
for (auto const& attr : entity->getDirectAttributes())
{
- std::cout << " .function(\"get" << attr.name << "\", &" << cppName(name) << "::get"
- << attr.name << ")\n";
+ out << " .function(\"get" << attr.name << "\", &" << cppName(name) << "::get"
+ << attr.name << ")\n";
if (!attr.readOnly)
{
- std::cout << " .function(\"set" << attr.name << "\", &" << cppName(name)
- << "::set" << attr.name << ")\n";
+ out << " .function(\"set" << attr.name << "\", &" << cppName(name) << "::set"
+ << attr.name << ")\n";
}
}
}
@@ -201,7 +243,8 @@ bool passByReference(rtl::Reference<TypeManager> const& manager, OUString const&
}
}
-void dumpType(rtl::Reference<TypeManager> const& manager, std::u16string_view name, bool isConst)
+void dumpType(std::ostream& out, rtl::Reference<TypeManager> const& manager,
+ std::u16string_view name, bool isConst)
{
sal_Int32 k;
std::vector<OString> args;
@@ -209,69 +252,69 @@ void dumpType(rtl::Reference<TypeManager> const& manager, std::u16string_view na
b2u(codemaker::UnoType::decompose(u2b(resolveAllTypedefs(manager, name)), &k, &args)));
if (isConst)
{
- std::cout << "const ";
+ out << "const ";
}
for (sal_Int32 i = 0; i != k; ++i)
{
- std::cout << "::css::uno::Sequence<";
+ out << "::css::uno::Sequence<";
}
switch (manager->getSort(n))
{
case codemaker::UnoType::Sort::Void:
- std::cout << "void";
+ out << "void";
break;
case codemaker::UnoType::Sort::Boolean:
- std::cout << "::sal_Bool";
+ out << "::sal_Bool";
break;
case codemaker::UnoType::Sort::Byte:
- std::cout << "::sal_Int8";
+ out << "::sal_Int8";
break;
case codemaker::UnoType::Sort::Short:
- std::cout << "::sal_Int16";
+ out << "::sal_Int16";
break;
case codemaker::UnoType::Sort::UnsignedShort:
- std::cout << "::sal_uInt16";
+ out << "::sal_uInt16";
break;
case codemaker::UnoType::Sort::Long:
- std::cout << "::sal_Int32";
+ out << "::sal_Int32";
break;
case codemaker::UnoType::Sort::UnsignedLong:
- std::cout << "::sal_uInt32";
+ out << "::sal_uInt32";
break;
case codemaker::UnoType::Sort::Hyper:
- std::cout << "::sal_Int64";
+ out << "::sal_Int64";
break;
case codemaker::UnoType::Sort::UnsignedHyper:
- std::cout << "::sal_uInt64";
+ out << "::sal_uInt64";
break;
case codemaker::UnoType::Sort::Float:
- std::cout << "float";
+ out << "float";
break;
case codemaker::UnoType::Sort::Double:
- std::cout << "double";
+ out << "double";
break;
case codemaker::UnoType::Sort::Char:
- std::cout << "::sal_Unicode";
+ out << "::sal_Unicode";
break;
case codemaker::UnoType::Sort::String:
- std::cout << "::rtl::OUString";
+ out << "::rtl::OUString";
break;
case codemaker::UnoType::Sort::Type:
- std::cout << "::css::uno::Type";
+ out << "::css::uno::Type";
break;
case codemaker::UnoType::Sort::Any:
- std::cout << "::css::uno::Any";
+ out << "::css::uno::Any";
break;
case codemaker::UnoType::Sort::Enum:
case codemaker::UnoType::Sort::PlainStruct:
case codemaker::UnoType::Sort::Exception:
- std::cout << cppName(n);
+ out << cppName(n);
break;
case codemaker::UnoType::Sort::PolymorphicStructTemplate:
- std::cout << cppName(n);
+ out << cppName(n);
if (!args.empty())
{
- std::cout << "<";
+ out << "<";
bool first = true;
for (auto const& arg : args)
{
@@ -281,17 +324,17 @@ void dumpType(rtl::Reference<TypeManager> const& manager, std::u16string_view na
}
else
{
- std::cout << ", ";
+ out << ", ";
}
- dumpType(manager, b2u(arg), false);
+ dumpType(out, manager, b2u(arg), false);
}
- std::cout << ">";
+ out << ">";
}
break;
case codemaker::UnoType::Sort::Interface:
- std::cout << "::css::uno::Reference<";
- std::cout << cppName(n);
- std::cout << ">";
+ out << "::css::uno::Reference<";
+ out << cppName(n);
+ out << ">";
break;
default:
throw CannotDumpException(OUString::Concat("unexpected entity \"") + name
@@ -299,11 +342,11 @@ void dumpType(rtl::Reference<TypeManager> const& manager, std::u16string_view na
}
for (sal_Int32 i = 0; i != k; ++i)
{
- std::cout << ">";
+ out << ">";
}
}
-void dumpParameters(rtl::Reference<TypeManager> const& manager,
+void dumpParameters(std::ostream& out, rtl::Reference<TypeManager> const& manager,
unoidl::InterfaceTypeEntity::Method const& method, bool declarations)
{
bool first = true;
@@ -315,7 +358,7 @@ void dumpParameters(rtl::Reference<TypeManager> const& manager,
}
else
{
- std::cout << ", ";
+ out << ", ";
}
bool isConst;
bool isRef;
@@ -332,58 +375,60 @@ void dumpParameters(rtl::Reference<TypeManager> const& manager,
// For the embind wrapper, we define a pointer instead of a reference:
if (declarations)
{
- dumpType(manager, param.type, isConst);
- std::cout << " ";
+ dumpType(out, manager, param.type, isConst);
+ out << " ";
}
if (isRef)
{
- std::cout << "*";
+ out << "*";
}
if (declarations)
{
- std::cout << " ";
+ out << " ";
}
- std::cout << param.name;
+ out << param.name;
}
}
-void dumpWrapper(rtl::Reference<TypeManager> const& manager, OUString const& interfaceName,
- unoidl::InterfaceTypeEntity::Method const& method, bool forReference)
+void dumpWrapper(std::ostream& out, rtl::Reference<TypeManager> const& manager,
+ OUString const& interfaceName, unoidl::InterfaceTypeEntity::Method const& method,
+ bool forReference)
{
- std::cout << " .function(\"" << method.name << "\", +[](";
+ out << " .function(\"" << method.name << "\", +[](";
if (forReference)
{
- std::cout << "::com::sun::star::uno::Reference<";
+ out << "::com::sun::star::uno::Reference<";
}
- std::cout << cppName(interfaceName);
+ out << cppName(interfaceName);
if (forReference)
{
- std::cout << ">";
+ out << ">";
}
- std::cout << " * the_self";
+ out << " * the_self";
if (!method.parameters.empty())
{
- std::cout << ", ";
+ out << ", ";
}
- dumpParameters(manager, method, true);
- std::cout << ") { return the_self->";
+ dumpParameters(out, manager, method, true);
+ out << ") { return the_self->";
if (forReference)
{
- std::cout << "get()->";
+ out << "get()->";
}
- std::cout << method.name << "(";
- dumpParameters(manager, method, false);
- std::cout << "); }, ::emscripten::allow_raw_pointers())\n";
+ out << method.name << "(";
+ dumpParameters(out, manager, method, false);
+ out << "); }, ::emscripten::allow_raw_pointers())\n";
}
-void dumpMethods(rtl::Reference<TypeManager> const& manager, OUString const& name,
- rtl::Reference<unoidl::InterfaceTypeEntity> const& entity, bool forReference)
+void dumpMethods(std::ostream& out, rtl::Reference<TypeManager> const& manager,
+ OUString const& name, rtl::Reference<unoidl::InterfaceTypeEntity> const& entity,
+ bool forReference)
{
for (auto const& meth : entity->getDirectMethods())
{
if (forReference)
{
- dumpWrapper(manager, name, meth, true);
+ dumpWrapper(out, manager, name, meth, true);
}
else if (std::any_of(
meth.parameters.begin(), meth.parameters.end(), [](auto const& parameter) {
@@ -391,15 +436,45 @@ void dumpMethods(rtl::Reference<TypeManager> const& manager, OUString const& nam
!= unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN;
}))
{
- dumpWrapper(manager, name, meth, false);
+ dumpWrapper(out, manager, name, meth, false);
}
else
{
- std::cout << " .function(\"" << meth.name << "\", &" << cppName(name)
- << "::" << meth.name << ")\n";
+ out << " .function(\"" << meth.name << "\", &" << cppName(name)
+ << "::" << meth.name << ")\n";
}
}
}
+
+void writeJsMap(std::ostream& out, Module const& module, std::string const& prefix)
+{
+ auto comma = false;
+ for (auto const& ifc : module.interfaces)
+ {
+ if (comma)
+ {
+ out << ",\n";
+ }
+ out << prefix << "'" << ifc.copy(ifc.lastIndexOf('.') + 1) << "': Module." << jsName(ifc)
+ << "Ref";
+ comma = true;
+ }
+ for (auto const & [ id, sub ] : module.modules)
+ {
+ if (comma)
+ {
+ out << ",\n";
+ }
+ out << prefix << "'" << id << "': {\n";
+ writeJsMap(out, *sub, prefix + " ");
+ out << prefix << "}";
+ comma = true;
+ }
+ if (comma)
+ {
+ out << "\n";
+ }
+}
}
SAL_IMPLEMENT_MAIN()
@@ -407,14 +482,16 @@ SAL_IMPLEMENT_MAIN()
try
{
auto const args = rtl_getAppCommandArgCount();
- if (args == 0)
+ if (args < 3)
{
badUsage();
}
- OUString prefix;
- rtl_getAppCommandArg(0, &prefix.pData);
+ OUString name;
+ rtl_getAppCommandArg(0, &name.pData);
+ auto const cppPathname = getPathnameArgument(1);
+ auto const jsPathname = getPathnameArgument(2);
rtl::Reference<TypeManager> mgr(new TypeManager);
- for (sal_uInt32 i = 1; i != args; ++i)
+ for (sal_uInt32 i = 3; i != args; ++i)
{
auto const & [ uri, primary ] = parseRegistryArgument(i);
try
@@ -427,67 +504,99 @@ SAL_IMPLEMENT_MAIN()
std::exit(EXIT_FAILURE);
}
}
+ auto const module = std::make_shared<Module>();
std::vector<OUString> interfaces;
for (auto const& prov : mgr->getPrimaryProviders())
{
- scan(prov->createRootCursor(), u"", interfaces);
+ scan(prov->createRootCursor(), u"", module.get(), interfaces);
}
- std::cout << "#include <emscripten/bind.h>\n"
- "#include <com/sun/star/uno/Any.hxx>\n"
- "#include <com/sun/star/uno/Reference.hxx>\n";
+ std::ofstream cppOut(cppPathname, std::ios_base::out | std::ios_base::trunc);
+ if (!cppOut)
+ {
+ std::cerr << "Cannot open \"" << cppPathname << "\" for writing\n";
+ std::exit(EXIT_FAILURE);
+ }
+ cppOut << "#include <emscripten/bind.h>\n"
+ "#include <com/sun/star/uno/Any.hxx>\n"
+ "#include <com/sun/star/uno/Reference.hxx>\n";
for (auto const& ifc : interfaces)
{
- std::cout << "#include <" << ifc.replace('.', '/') << ".hpp>\n";
+ cppOut << "#include <" << ifc.replace('.', '/') << ".hpp>\n";
}
- std::cout << "\n"
- "// TODO: This is a temporary workaround that likely causes the Embind UNO\n"
- "// bindings to leak memory. Reference counting and cloning mechanisms of\n"
- "// Embind should be investigated to figure out what exactly we need here:\n"
- "namespace emscripten::internal {\n";
+ cppOut << "\n"
+ "// TODO: This is a temporary workaround that likely causes the Embind UNO\n"
+ "// bindings to leak memory. Reference counting and cloning mechanisms of\n"
+ "// Embind should be investigated to figure out what exactly we need here:\n"
+ "namespace emscripten::internal {\n";
for (auto const& ifc : interfaces)
{
- std::cout << " template<> void raw_destructor<" << cppName(ifc) << ">("
- << cppName(ifc) << " *) {}\n";
+ cppOut << " template<> void raw_destructor<" << cppName(ifc) << ">(" << cppName(ifc)
+ << " *) {}\n";
}
- std::cout << "}\n\n"
- "EMSCRIPTEN_BINDINGS(uno_bindings_"
- << prefix << ") {\n";
+ cppOut << "}\n\n"
+ "EMSCRIPTEN_BINDINGS(unoembind_"
+ << name << ") {\n";
for (auto const& ifc : interfaces)
{
auto const ent = mgr->getManager()->findEntity(ifc);
assert(ent.is());
assert(ent->getSort() == unoidl::Entity::SORT_INTERFACE_TYPE);
rtl::Reference const ifcEnt(static_cast<unoidl::InterfaceTypeEntity*>(ent.get()));
- std::cout << " ::emscripten::class_<" << cppName(ifc) << ">(\"" << jsName(ifc)
- << "\")\n";
- dumpAttributes(ifc, ifcEnt);
- dumpMethods(mgr, ifc, ifcEnt, false);
- std::cout << " ;\n"
- " ::emscripten::class_<::com::sun::star::uno::Reference<"
- << cppName(ifc)
- << ">, ::emscripten::base<::com::sun::star::uno::BaseReference>>(\""
- << jsName(ifc)
- << "Ref\")\n"
- " .constructor<>()\n"
- " .constructor<::com::sun::star::uno::BaseReference, "
- "::com::sun::star::uno::UnoReference_Query>()\n"
- " .function(\"is\", &::com::sun::star::uno::Reference<"
- << cppName(ifc)
- << ">::is)\n"
- " .function(\"get\", &::com::sun::star::uno::Reference<"
- << cppName(ifc)
- << ">::get, ::emscripten::allow_raw_pointers())\n"
- " .function(\"set\", "
- "::emscripten::select_overload<bool(::com::sun::star::uno::Any const "
- "&, "
- "com::sun::star::uno::UnoReference_Query)>(&::com::sun::star::uno::"
- "Reference<"
- << cppName(ifc) << ">::set))\n";
- dumpAttributes(ifc, ifcEnt);
- dumpMethods(mgr, ifc, ifcEnt, true);
- std::cout << " ;\n";
+ cppOut << " ::emscripten::class_<" << cppName(ifc) << ">(\"" << jsName(ifc)
+ << "\")\n";
+ dumpAttributes(cppOut, ifc, ifcEnt);
+ dumpMethods(cppOut, mgr, ifc, ifcEnt, false);
+ cppOut << " ;\n"
+ " ::emscripten::class_<::com::sun::star::uno::Reference<"
+ << cppName(ifc)
+ << ">, ::emscripten::base<::com::sun::star::uno::BaseReference>>(\""
+ << jsName(ifc)
+ << "Ref\")\n"
+ " .constructor<>()\n"
+ " .constructor<::com::sun::star::uno::BaseReference, "
+ "::com::sun::star::uno::UnoReference_Query>()\n"
+ " .function(\"is\", &::com::sun::star::uno::Reference<"
+ << cppName(ifc)
+ << ">::is)\n"
+ " .function(\"get\", &::com::sun::star::uno::Reference<"
+ << cppName(ifc)
+ << ">::get, ::emscripten::allow_raw_pointers())\n"
+ " .function(\"set\", "
+ "::emscripten::select_overload<bool(::com::sun::star::uno::Any const "
+ "&, "
+ "com::sun::star::uno::UnoReference_Query)>(&::com::sun::star::uno::"
+ "Reference<"
+ << cppName(ifc) << ">::set))\n";
+ dumpAttributes(cppOut, ifc, ifcEnt);
+ dumpMethods(cppOut, mgr, ifc, ifcEnt, true);
+ cppOut << " ;\n";
+ }
+ cppOut << "}\n";
+ cppOut.close();
+ if (!cppOut)
+ {
+ std::cerr << "Failed to write \"" << cppPathname << "\"\n";
+ std::exit(EXIT_FAILURE);
+ }
+ std::ofstream jsOut(jsPathname, std::ios_base::out | std::ios_base::trunc);
+ if (!jsOut)
+ {
+ std::cerr << "Cannot open \"" << jsPathname << "\" for writing\n";
+ std::exit(EXIT_FAILURE);
+ }
+ jsOut << "Module.init_unoembind_" << name
+ << " = function() {\n"
+ " Module.unoembind_"
+ << name << " = {\n";
+ writeJsMap(jsOut, *module, " ");
+ jsOut << " };\n"
+ "};\n";
+ jsOut.close();
+ if (!jsOut)
+ {
+ std::cerr << "Failed to write \"" << jsPathname << "\"\n";
+ std::exit(EXIT_FAILURE);
}
- std::cout << "}\n";
return EXIT_SUCCESS;
}
catch (unoidl::FileFormatException const& e)