Kaydet (Commit) fc54915c authored tarafından Stephan Bergmann's avatar Stephan Bergmann

Replace reg2unoidl with unoidl-write

...that can also generate an .rdb containing a specific set of entities,
intended to replace idlc (when reading directly from .idl source registries).

Change-Id: I630ce4640828979d7952dc24dbbef80a42a8140a
üst 95e566b9
...@@ -48,7 +48,6 @@ $(eval $(call gb_Helper_register_executables,NONE, \ ...@@ -48,7 +48,6 @@ $(eval $(call gb_Helper_register_executables,NONE, \
pdfunzip \ pdfunzip \
pocheck \ pocheck \
propex \ propex \
reg2unoidl \
regsvrex \ regsvrex \
rsc \ rsc \
saxparser \ saxparser \
...@@ -60,6 +59,7 @@ $(eval $(call gb_Helper_register_executables,NONE, \ ...@@ -60,6 +59,7 @@ $(eval $(call gb_Helper_register_executables,NONE, \
treex \ treex \
uiex \ uiex \
ulfex \ ulfex \
unoidl-write \
xrmex \ xrmex \
)) ))
......
...@@ -850,11 +850,11 @@ gb_BUILD_HELPER_LIBS := basegfx \ ...@@ -850,11 +850,11 @@ gb_BUILD_HELPER_LIBS := basegfx \
gb_BUILD_HELPER_TOOLS := cppumaker \ gb_BUILD_HELPER_TOOLS := cppumaker \
idlc \ idlc \
reg2unoidl \
regcompare \ regcompare \
regmerge \ regmerge \
rsc \ rsc \
svidl svidl \
unoidl-write \
define gb_LinkTarget__is_build_lib define gb_LinkTarget__is_build_lib
$(if $(filter $(1),$(foreach lib,$(gb_BUILD_HELPER_LIBS),$(call gb_Library_get_linktargetname,$(lib)))),$(true),$(false)) $(if $(filter $(1),$(foreach lib,$(gb_BUILD_HELPER_LIBS),$(call gb_Library_get_linktargetname,$(lib)))),$(true),$(false))
......
...@@ -80,7 +80,7 @@ endif ...@@ -80,7 +80,7 @@ endif
gb_UnoApiTarget_REGCOMPAREDEPS := $(call gb_Executable_get_runtime_dependencies,regcompare) gb_UnoApiTarget_REGCOMPAREDEPS := $(call gb_Executable_get_runtime_dependencies,regcompare)
gb_UnoApiTarget_REGCOMPARECOMMAND := SOLARBINDIR=$(OUTDIR_FOR_BUILD)/bin $(call gb_Executable_get_command,regcompare) gb_UnoApiTarget_REGCOMPARECOMMAND := SOLARBINDIR=$(OUTDIR_FOR_BUILD)/bin $(call gb_Executable_get_command,regcompare)
gb_UnoApiTarget_REGMERGEDEPS := $(call gb_Executable_get_runtime_dependencies,regmerge) $(call gb_Executable_get_runtime_dependencies,reg2unoidl) gb_UnoApiTarget_REGMERGEDEPS := $(call gb_Executable_get_runtime_dependencies,regmerge) $(call gb_Executable_get_runtime_dependencies,unoidl-write)
gb_UnoApiTarget_REGMERGECOMMAND := SOLARBINDIR=$(OUTDIR_FOR_BUILD)/bin $(call gb_Executable_get_command,regmerge) gb_UnoApiTarget_REGMERGECOMMAND := SOLARBINDIR=$(OUTDIR_FOR_BUILD)/bin $(call gb_Executable_get_command,regmerge)
gb_UnoApiTarget_TYPESRDB := $(call gb_UnoApiTarget_get_target,types) gb_UnoApiTarget_TYPESRDB := $(call gb_UnoApiTarget_get_target,types)
...@@ -90,7 +90,7 @@ RESPONSEFILE=$(call var2file,$(shell $(gb_MKTEMP)),500,$(1).oldformat $(2) $(3)) ...@@ -90,7 +90,7 @@ RESPONSEFILE=$(call var2file,$(shell $(gb_MKTEMP)),500,$(1).oldformat $(2) $(3))
$(gb_UnoApiTarget_REGMERGECOMMAND) @$${RESPONSEFILE} && \ $(gb_UnoApiTarget_REGMERGECOMMAND) @$${RESPONSEFILE} && \
rm -f $${RESPONSEFILE} && \ rm -f $${RESPONSEFILE} && \
SOLARBINDIR=$(OUTDIR_FOR_BUILD)/bin \ SOLARBINDIR=$(OUTDIR_FOR_BUILD)/bin \
$(call gb_Executable_get_command,reg2unoidl) \ $(call gb_Executable_get_command,unoidl-write) \
$(foreach rdb,$(4),$(call gb_UnoApiTarget_get_target,$(rdb))) \ $(foreach rdb,$(4),$(call gb_UnoApiTarget_get_target,$(rdb))) \
$(1).oldformat $(1) $(1).oldformat $(1)
endef endef
......
...@@ -7,13 +7,13 @@ ...@@ -7,13 +7,13 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
# #
$(eval $(call gb_Executable_Executable,reg2unoidl)) $(eval $(call gb_Executable_Executable,unoidl-write))
$(eval $(call gb_Executable_add_exception_objects,reg2unoidl, \ $(eval $(call gb_Executable_add_exception_objects,unoidl-write, \
unoidl/source/reg2unoidl \ unoidl/source/unoidl-write \
)) ))
$(eval $(call gb_Executable_use_libraries,reg2unoidl, \ $(eval $(call gb_Executable_use_libraries,unoidl-write, \
sal \ sal \
salhelper \ salhelper \
unoidl \ unoidl \
......
...@@ -14,7 +14,7 @@ $(eval $(call gb_Module_add_targets,unoidl, \ ...@@ -14,7 +14,7 @@ $(eval $(call gb_Module_add_targets,unoidl, \
)) ))
$(eval $(call gb_Module_add_targets_for_build,unoidl, \ $(eval $(call gb_Module_add_targets_for_build,unoidl, \
Executable_reg2unoidl \ Executable_unoidl-write \
)) ))
# vim: set noet sw=4 ts=4: # vim: set noet sw=4 ts=4:
...@@ -8,16 +8,16 @@ for both the new and the old types.rdb formats (unoidl::loadProvider tries both ...@@ -8,16 +8,16 @@ for both the new and the old types.rdb formats (unoidl::loadProvider tries both
implementations in turn for a given file, so the old format is still supported implementations in turn for a given file, so the old format is still supported
transparently for now). transparently for now).
Executable_reg2unoidl is a helper tool to convert from the old to the new Executable_unoidl-write is a helper tool to convert from the old to the new
types.rdb format. It is currently used at build-time. idlc still generates the types.rdb format. It is currently used at build-time. idlc still generates the
old format, and any new-format files (used at build-time only, or included in old format, and any new-format files (used at build-time only, or included in
installation sets in URE or program/types/ or as part of bundled extensions that installation sets in URE or program/types/ or as part of bundled extensions that
are created during the build and not merely included as pre-built .oxt files) are created during the build and not merely included as pre-built .oxt files)
are explicitly generated via reg2unoidl. The SDK is still designed to generate are explicitly generated via unoidl-write. The SDK is still designed to
old-format files exclusively (especially, any non-bundled extensions will only generate old-format files exclusively (especially, any non-bundled extensions
contain old-format files for now; that allows to modify the new format further will only contain old-format files for now; that allows to modify the new format
without having to worry about compatibility with multiple versions of that further without having to worry about compatibility with multiple versions of
format). that format).
== Specification of the new UNOIDL types.rdb format == == Specification of the new UNOIDL types.rdb format ==
...@@ -56,7 +56,7 @@ The following definitions are used throughout: ...@@ -56,7 +56,7 @@ The following definitions are used throughout:
* Map: zero or more Entries * Map: zero or more Entries
The file starts with an 8 byte header, followed by information about the root The file starts with an 8 byte header, followed by information about the root
map (reg2unoidl generates files in a single depth-first pass, so the root map map (unoidl-write generates files in a single depth-first pass, so the root map
itself is at the end of the file): itself is at the end of the file):
* 7 byte magic header "UNOIDL\xFF" * 7 byte magic header "UNOIDL\xFF"
...@@ -65,11 +65,12 @@ itself is at the end of the file): ...@@ -65,11 +65,12 @@ itself is at the end of the file):
* UInt32 number of entries of root Map * UInt32 number of entries of root Map
... ...
Files generated by reg2unoidl follow that by a Files generated by unoidl-write follow that by a
"\0** Created by LibreOffice " LIBO_VERSION_DOTTED " reg2unoidl **\0" "\0** Created by LibreOffice " LIBO_VERSION_DOTTED " unoidl-write **\0"
banner (cf. config_host/config_version.h.in), as a debugging aid. banner (cf. config_host/config_version.h.in), as a debugging aid. (Old versions
used "reg2unoidl" instead of "unoidl-write" in that banner.)
Layout of per-entry payload in the root or a module Map: Layout of per-entry payload in the root or a module Map:
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <new> #include <new>
#include "osl/file.h" #include "osl/file.h"
#include "osl/file.hxx"
#include "osl/thread.h" #include "osl/thread.h"
#include "rtl/character.hxx" #include "rtl/character.hxx"
#include "rtl/ref.hxx" #include "rtl/ref.hxx"
...@@ -86,6 +87,20 @@ private: ...@@ -86,6 +87,20 @@ private:
{ return rtl::Reference<Entity>(); } //TODO { return rtl::Reference<Entity>(); } //TODO
}; };
class SourceModuleEntity: public ModuleEntity {
public:
SourceModuleEntity() {}
private:
virtual ~SourceModuleEntity() throw () {}
virtual std::vector<OUString> getMemberNames() const
{ return std::vector<OUString>(); } //TODO
virtual rtl::Reference< MapCursor > createCursor() const
{ return new Cursor; }
};
} }
SourceProvider::SourceProvider( SourceProvider::SourceProvider(
...@@ -147,53 +162,67 @@ rtl::Reference<Entity> SourceProvider::findEntity(OUString const & name) const { ...@@ -147,53 +162,67 @@ rtl::Reference<Entity> SourceProvider::findEntity(OUString const & name) const {
throw FileFormatException( //TODO throw FileFormatException( //TODO
"", "Illegal UNOIDL identifier \"" + name + "\""); "", "Illegal UNOIDL identifier \"" + name + "\"");
} }
OUString uri(uri_ + buf.makeStringAndClear() + ".idl"); OUString uri(uri_ + buf.makeStringAndClear());
oslFileHandle handle;
oslFileError e = osl_openFile(uri.pData, &handle, osl_File_OpenFlag_Read);
switch (e) {
case osl_File_E_None:
break;
case osl_File_E_NOENT:
cache_.insert(
std::map< OUString, rtl::Reference<Entity> >::value_type(
name, rtl::Reference<Entity>()));
return rtl::Reference<Entity>();
default:
throw FileFormatException(uri, "cannot open: " + OUString::number(e));
}
sal_uInt64 size;
e = osl_getFileSize(handle, &size);
if (e != osl_File_E_None) {
oslFileError e2 = osl_closeFile(handle);
SAL_WARN_IF(
e2 != osl_File_E_None, "unoidl",
"cannot close " << uri << ": " << +e2);
throw FileFormatException(
uri, "cannot get size: " + OUString::number(e));
}
void * address;
e = osl_mapFile(handle, &address, size, 0, osl_File_MapFlag_RandomAccess);
if (e != osl_File_E_None) {
oslFileError e2 = osl_closeFile(handle);
SAL_WARN_IF(
e2 != osl_File_E_None, "unoidl",
"cannot close " << uri << ": " << +e2);
throw FileFormatException(uri, "cannot mmap: " + OUString::number(e));
}
rtl::Reference<Entity> ent; rtl::Reference<Entity> ent;
try { osl::DirectoryItem item;
ent = parse(manager_, name, uri, address, size); osl::FileStatus status(osl_FileStatus_Mask_Type);
} catch (...) { if (osl::DirectoryItem::get(uri, item) == osl::FileBase::E_None
&& item.getFileStatus(status) == osl::FileBase::E_None
&& status.getFileType() == osl::FileStatus::Directory)
{
ent = new SourceModuleEntity;
} else {
uri += ".idl";
oslFileHandle handle;
oslFileError e = osl_openFile(
uri.pData, &handle, osl_File_OpenFlag_Read);
switch (e) {
case osl_File_E_None:
break;
case osl_File_E_NOENT:
cache_.insert(
std::map< OUString, rtl::Reference<Entity> >::value_type(
name, rtl::Reference<Entity>()));
return rtl::Reference<Entity>();
default:
throw FileFormatException(
uri, "cannot open: " + OUString::number(e));
}
sal_uInt64 size;
e = osl_getFileSize(handle, &size);
if (e != osl_File_E_None) {
oslFileError e2 = osl_closeFile(handle);
SAL_WARN_IF(
e2 != osl_File_E_None, "unoidl",
"cannot close " << uri << ": " << +e2);
throw FileFormatException(
uri, "cannot get size: " + OUString::number(e));
}
void * address;
e = osl_mapFile(
handle, &address, size, 0, osl_File_MapFlag_RandomAccess);
if (e != osl_File_E_None) {
oslFileError e2 = osl_closeFile(handle);
SAL_WARN_IF(
e2 != osl_File_E_None, "unoidl",
"cannot close " << uri << ": " << +e2);
throw FileFormatException(
uri, "cannot mmap: " + OUString::number(e));
}
try {
ent = parse(manager_, name, uri, address, size);
} catch (...) {
e = osl_unmapMappedFile(handle, address, size);
SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot unmap: " << +e);
e = osl_closeFile(handle);
SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot close: " << +e);
throw;
}
e = osl_unmapMappedFile(handle, address, size); e = osl_unmapMappedFile(handle, address, size);
SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot unmap: " << +e); SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot unmap: " << +e);
e = osl_closeFile(handle); e = osl_closeFile(handle);
SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot close: " << +e); SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot close: " << +e);
throw;
} }
e = osl_unmapMappedFile(handle, address, size);
SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot unmap: " << +e);
e = osl_closeFile(handle);
SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot close: " << +e);
cache_.insert( cache_.insert(
std::map< OUString, rtl::Reference<Entity> >::value_type(name, ent)); std::map< OUString, rtl::Reference<Entity> >::value_type(name, ent));
return ent; return ent;
......
...@@ -34,9 +34,38 @@ ...@@ -34,9 +34,38 @@
namespace { namespace {
OUString getArgumentUri(sal_uInt32 argument) { void badUsage() {
std::cerr
<< "Usage:" << std::endl << std::endl
<< " unoidl-write [<registries>] [@<entities file>] <unoidl file>"
<< std::endl << std::endl
<< ("where each <registry> is either a new- or legacy-format .rdb"
" file or a")
<< std::endl
<< ("root directory of an .idl file tree, and the UTF-8 encoded"
" <entities file>")
<< std::endl
<< ("contains zero or more space-separated names of (non-module)"
" entities to include")
<< std::endl
<< ("in the output, and, if omitted, defaults to the complete content"
" of the final")
<< std::endl << "<registry>, if any." << std::endl;
std::exit(EXIT_FAILURE);
}
OUString getArgumentUri(sal_uInt32 argument, bool * entities) {
OUString arg; OUString arg;
rtl_getAppCommandArg(argument, &arg.pData); rtl_getAppCommandArg(argument, &arg.pData);
if (arg.startsWith("@")) {
if (entities == 0) {
badUsage();
}
*entities = true;
arg = arg.copy(1);
} else if (entities != 0) {
*entities = false;
}
OUString url; OUString url;
osl::FileBase::RC e1 = osl::FileBase::getFileURLFromSystemPath(arg, url); osl::FileBase::RC e1 = osl::FileBase::getFileURLFromSystemPath(arg, url);
if (e1 != osl::FileBase::E_None) { if (e1 != osl::FileBase::E_None) {
...@@ -64,22 +93,6 @@ OUString getArgumentUri(sal_uInt32 argument) { ...@@ -64,22 +93,6 @@ OUString getArgumentUri(sal_uInt32 argument) {
return abs; return abs;
} }
rtl::Reference< unoidl::Provider > load(
rtl::Reference< unoidl::Manager > const & manager, OUString const & uri)
{
try {
return unoidl::loadProvider(manager, uri);
} catch (unoidl::NoSuchFileException &) {
std::cerr << "Input <" << uri << "> does not exist" << std::endl;
std::exit(EXIT_FAILURE);
} catch (unoidl::FileFormatException & e) {
std::cerr
<< "Cannot read input <" << uri << ">: " << e.getDetail()
<< std::endl;
std::exit(EXIT_FAILURE);
}
}
sal_uInt64 getOffset(osl::File & file) { sal_uInt64 getOffset(osl::File & file) {
sal_uInt64 off; sal_uInt64 off;
osl::FileBase::RC e = file.getPos(off); osl::FileBase::RC e = file.getPos(off);
...@@ -292,6 +305,7 @@ struct Item { ...@@ -292,6 +305,7 @@ struct Item {
{} {}
rtl::Reference< unoidl::Entity > entity; rtl::Reference< unoidl::Entity > entity;
std::map< OUString, Item > module;
sal_uInt64 nameOffset; sal_uInt64 nameOffset;
sal_uInt64 dataOffset; sal_uInt64 dataOffset;
}; };
...@@ -310,35 +324,139 @@ struct ConstItem { ...@@ -310,35 +324,139 @@ struct ConstItem {
sal_uInt64 dataOffset; sal_uInt64 dataOffset;
}; };
sal_uInt64 writeMap( void mapEntities(
osl::File & file, rtl::Reference< unoidl::MapCursor > const & cursor, rtl::Reference< unoidl::Manager > const & manager, OUString const & uri,
std::size_t * rootSize) std::map< OUString, Item > & map)
{ {
assert(cursor.is()); assert(manager.is());
std::map< OUString, Item > map; osl::File f(uri);
osl::FileBase::RC e = f.open(osl_File_OpenFlag_Read);
if (e != osl::FileBase::E_None) {
std::cerr
<< "Cannot open <" << f.getURL() << "> for reading, error code "
<< +e << std::endl;
std::exit(EXIT_FAILURE);
}
for (;;) { for (;;) {
OUString name; sal_Bool eof;
rtl::Reference< unoidl::Entity > ent(cursor->getNext(&name)); e = f.isEndOfFile(&eof);
if (!ent.is()) { if (e != osl::FileBase::E_None) {
std::cerr
<< "Cannot check <" << f.getURL() << "> for EOF, error code "
<< +e << std::endl;
std::exit(EXIT_FAILURE);
}
if (eof) {
break; break;
} }
if (!map.insert(std::make_pair(name, Item(ent))).second) { rtl::ByteSequence s1;
std::cout << "Duplicate name \"" << name << '"' << std::endl; e = f.readLine(s1);
if (e != osl::FileBase::E_None) {
std::cerr
<< "Cannot read from <" << f.getURL() << ">, error code "
<< +e << std::endl;
std::exit(EXIT_FAILURE);
}
OUString s2;
if (!rtl_convertStringToUString(
&s2.pData, reinterpret_cast< char const * >(s1.getConstArray()),
s1.getLength(), RTL_TEXTENCODING_UTF8,
(RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
| RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
| RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)))
{
std::cerr
<< "Cannot interpret line read from <" << f.getURL()
<< "> as UTF-8" << std::endl;
std::exit(EXIT_FAILURE); std::exit(EXIT_FAILURE);
} }
for (sal_Int32 i = 0; i != -1;) {
OUString t(s2.getToken(0, ' ', i));
if (!t.isEmpty()) {
rtl::Reference< unoidl::Entity > ent(manager->findEntity(t));
if (!ent.is()) {
std::cerr
<< "Unknown entity \"" << t << "\" read from <"
<< f.getURL() << ">" << std::endl;
std::exit(EXIT_FAILURE);
}
if (ent->getSort() == unoidl::Entity::SORT_MODULE) {
std::cerr
<< "Module entity \"" << t << "\" read from <"
<< f.getURL() << ">" << std::endl;
std::exit(EXIT_FAILURE);
}
std::map< OUString, Item > * map2 = &map;
for (sal_Int32 j = 0;;) {
OUString id(t.getToken(0, '.', j));
if (j == -1) {
map2->insert(std::make_pair(id, Item(ent)));
break;
}
std::map< OUString, Item >::iterator k(map2->find(id));
if (k == map2->end()) {
rtl::Reference< unoidl::Entity > ent2(
manager->findEntity(t.copy(0, j - 1)));
assert(ent2.is());
k = map2->insert(std::make_pair(id, Item(ent2))).first;
}
assert(
k->second.entity->getSort()
== unoidl::Entity::SORT_MODULE);
map2 = &k->second.module;
}
}
}
}
e = f.close();
if (e != osl::FileBase::E_None) {
std::cerr
<< "Cannot close <" << f.getURL() << "> after reading, error code "
<< +e << std::endl;
std::exit(EXIT_FAILURE);
} }
}
void mapCursor(
rtl::Reference< unoidl::MapCursor > const & cursor,
std::map< OUString, Item > & map)
{
if (cursor.is()) {
for (;;) {
OUString name;
rtl::Reference< unoidl::Entity > ent(cursor->getNext(&name));
if (!ent.is()) {
break;
}
std::pair< std::map< OUString, Item >::iterator, bool > i(
map.insert(std::make_pair(name, Item(ent))));
if (!i.second) {
std::cout << "Duplicate name \"" << name << '"' << std::endl;
std::exit(EXIT_FAILURE);
}
if (i.first->second.entity->getSort()
== unoidl::Entity::SORT_MODULE)
{
mapCursor(
rtl::Reference< unoidl::ModuleEntity >(
static_cast< unoidl::ModuleEntity * >(
i.first->second.entity.get()))->createCursor(),
i.first->second.module);
}
}
}
}
sal_uInt64 writeMap(
osl::File & file, std::map< OUString, Item > & map, std::size_t * rootSize)
{
for (std::map< OUString, Item >::iterator i(map.begin()); i != map.end(); for (std::map< OUString, Item >::iterator i(map.begin()); i != map.end();
++i) ++i)
{ {
switch (i->second.entity->getSort()) { switch (i->second.entity->getSort()) {
case unoidl::Entity::SORT_MODULE: case unoidl::Entity::SORT_MODULE:
{ i->second.dataOffset = writeMap(file, i->second.module, 0);
rtl::Reference< unoidl::ModuleEntity > ent2( break;
static_cast< unoidl::ModuleEntity * >(
i->second.entity.get()));
i->second.dataOffset = writeMap(file, ent2->createCursor(), 0);
break;
}
case unoidl::Entity::SORT_ENUM_TYPE: case unoidl::Entity::SORT_ENUM_TYPE:
{ {
rtl::Reference< unoidl::EnumTypeEntity > ent2( rtl::Reference< unoidl::EnumTypeEntity > ent2(
...@@ -905,73 +1023,90 @@ sal_uInt64 writeMap( ...@@ -905,73 +1023,90 @@ sal_uInt64 writeMap(
} }
SAL_IMPLEMENT_MAIN() { SAL_IMPLEMENT_MAIN() {
sal_uInt32 args = rtl_getAppCommandArgCount();
if (args < 2) {
std::cerr
<< "Usage: reg2unoidl <extra .rdb files> <.rdb file> <unoidl file>"
<< std::endl;
std::exit(EXIT_FAILURE);
}
rtl::Reference< unoidl::Manager > mgr(new unoidl::Manager);
for (sal_uInt32 i = 0; i != args - 2; ++i) {
mgr->addProvider(load(mgr, getArgumentUri(i)));
}
rtl::Reference< unoidl::Provider > prov(
load(mgr, getArgumentUri(args - 2)));
osl::File f(getArgumentUri(args - 1));
osl::FileBase::RC e = f.open(osl_File_OpenFlag_Write);
if (e == osl::FileBase::E_NOENT) {
e = f.open(osl_File_OpenFlag_Write | osl_File_OpenFlag_Create);
}
if (e != osl::FileBase::E_None) {
std::cerr
<< "Cannot open <" << f.getURL() << "> for writing, error code "
<< +e << std::endl;
std::exit(EXIT_FAILURE);
}
write(f, "UNOIDL\xFF\0", 8);
write32(f, 0); // root map offset
write32(f, 0); // root map size
write(
f,
RTL_CONSTASCII_STRINGPARAM(
"\0** Created by LibreOffice " LIBO_VERSION_DOTTED
" reg2unoidl **\0"));
sal_uInt64 off;
std::size_t size;
try { try {
off = writeMap(f, prov->createRootCursor(), &size); sal_uInt32 args = rtl_getAppCommandArgCount();
if (args == 0) {
badUsage();
}
rtl::Reference< unoidl::Manager > mgr(new unoidl::Manager);
bool entities = false;
rtl::Reference< unoidl::Provider > prov;
std::map< OUString, Item > map;
for (sal_uInt32 i = 0; i != args - 1; ++i) {
assert(args > 1);
OUString uri(getArgumentUri(i, i == args - 2 ? &entities : 0));
if (entities) {
mapEntities(mgr, uri, map);
} else {
try {
prov = unoidl::loadProvider(mgr, uri);
} catch (unoidl::NoSuchFileException &) {
std::cerr
<< "Input <" << uri << "> does not exist" << std::endl;
std::exit(EXIT_FAILURE);
}
mgr->addProvider(prov);
}
}
if (!entities) {
mapCursor(
(prov.is()
? prov->createRootCursor()
: rtl::Reference< unoidl::MapCursor >()),
map);
}
osl::File f(getArgumentUri(args - 1, 0));
osl::FileBase::RC e = f.open(osl_File_OpenFlag_Write);
if (e == osl::FileBase::E_NOENT) {
e = f.open(osl_File_OpenFlag_Write | osl_File_OpenFlag_Create);
}
if (e != osl::FileBase::E_None) {
std::cerr
<< "Cannot open <" << f.getURL() << "> for writing, error code "
<< +e << std::endl;
std::exit(EXIT_FAILURE);
}
write(f, "UNOIDL\xFF\0", 8);
write32(f, 0); // root map offset
write32(f, 0); // root map size
write(
f,
RTL_CONSTASCII_STRINGPARAM(
"\0** Created by LibreOffice " LIBO_VERSION_DOTTED
" unoidl-write **\0"));
std::size_t size;
sal_uInt64 off = writeMap(f, map, &size);
e = f.setSize(getOffset(f)); // truncate in case it already existed
if (e != osl::FileBase::E_None) {
std::cerr
<< "Cannot set size of <" << f.getURL() << ">, error code "
<< +e << std::endl;
std::exit(EXIT_FAILURE);
}
e = f.setPos(osl_Pos_Absolut, 8);
if (e != osl::FileBase::E_None) {
std::cerr
<< "Cannot rewind current position in <" << f.getURL()
<< ">, error code " << +e << std::endl;
std::exit(EXIT_FAILURE);
}
write32(f, off);
write32(f, size);
// overflow from std::map::size_type -> sal_uInt64 is unrealistic
e = f.close();
if (e != osl::FileBase::E_None) {
std::cerr
<< "Cannot close <" << f.getURL()
<< "> after writing, error code " << +e << std::endl;
std::exit(EXIT_FAILURE);
}
return EXIT_SUCCESS;
} catch (unoidl::FileFormatException & e1) { } catch (unoidl::FileFormatException & e1) {
std::cerr std::cerr
<< "Bad input <" << e1.getUri() << ">: " << e1.getDetail() << "Bad input <" << e1.getUri() << ">: " << e1.getDetail()
<< std::endl; << std::endl;
std::exit(EXIT_FAILURE); std::exit(EXIT_FAILURE);
} }
e = f.setSize(getOffset(f)); // truncate in case it already existed
if (e != osl::FileBase::E_None) {
std::cerr
<< "Cannot set size of <" << f.getURL() << ">, error code " << +e
<< std::endl;
std::exit(EXIT_FAILURE);
}
e = f.setPos(osl_Pos_Absolut, 8);
if (e != osl::FileBase::E_None) {
std::cerr
<< "Cannot rewind current position in <" << f.getURL()
<< ">, error code " << +e << std::endl;
std::exit(EXIT_FAILURE);
}
write32(f, off);
write32(f, size);
// overflow from std::map::size_type -> sal_uInt64 is unrealistic
e = f.close();
if (e != osl::FileBase::E_None) {
std::cerr
<< "Cannot close <" << f.getURL() << "> after writing, error code "
<< +e << std::endl;
std::exit(EXIT_FAILURE);
}
return EXIT_SUCCESS;
} }
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment