LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/unoidl/source - reg2unoidl.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 488 564 86.5 %
Date: 2013-07-09 Functions: 27 28 96.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  */
       9             : 
      10             : #include "sal/config.h"
      11             : 
      12             : #include <cassert>
      13             : #include <cstddef>
      14             : #include <cstdlib>
      15             : #include <iostream>
      16             : #include <map>
      17             : #include <utility>
      18             : #include <vector>
      19             : 
      20             : #include "config_version.h"
      21             : #include "osl/endian.h"
      22             : #include "osl/file.h"
      23             : #include "osl/file.hxx"
      24             : #include "osl/process.h"
      25             : #include "rtl/process.h"
      26             : #include "rtl/string.h"
      27             : #include "rtl/string.hxx"
      28             : #include "rtl/textenc.h"
      29             : #include "rtl/textcvt.h"
      30             : #include "rtl/ustring.hxx"
      31             : #include "sal/macros.h"
      32             : #include "sal/main.h"
      33             : #include "unoidl/unoidl.hxx"
      34             : 
      35             : namespace {
      36             : 
      37          25 : OUString getArgumentUri(sal_uInt32 argument) {
      38          25 :     OUString arg;
      39          25 :     rtl_getAppCommandArg(argument, &arg.pData);
      40          50 :     OUString url;
      41          25 :     osl::FileBase::RC e1 = osl::FileBase::getFileURLFromSystemPath(arg, url);
      42          25 :     if (e1 != osl::FileBase::E_None) {
      43             :         std::cerr
      44           0 :             << "Cannot convert \"" << arg << "\" to file URL, error code "
      45           0 :             << +e1 << std::endl;
      46           0 :         std::exit(EXIT_FAILURE);
      47             :     }
      48          50 :     OUString cwd;
      49          25 :     oslProcessError e2 = osl_getProcessWorkingDir(&cwd.pData);
      50          25 :     if (e2 != osl_Process_E_None) {
      51             :         std::cerr
      52           0 :             << "Cannot obtain working directory, error code " << +e2
      53           0 :             << std::endl;
      54           0 :         std::exit(EXIT_FAILURE);
      55             :     }
      56          25 :     OUString abs;
      57          25 :     e1 = osl::FileBase::getAbsoluteFileURL(cwd, url, abs);
      58          25 :     if (e1 != osl::FileBase::E_None) {
      59             :         std::cerr
      60           0 :             << "Cannot make \"" << url
      61           0 :             << "\" into an absolute file URL, error code " << +e1 << std::endl;
      62           0 :         std::exit(EXIT_FAILURE);
      63             :     }
      64          50 :     return abs;
      65             : }
      66             : 
      67          17 : rtl::Reference< unoidl::Provider > load(
      68             :     rtl::Reference< unoidl::Manager > const & manager, OUString const & uri)
      69             : {
      70             :     try {
      71          17 :         return unoidl::loadProvider(manager, uri);
      72           0 :     } catch (unoidl::NoSuchFileException &) {
      73           0 :         std::cerr << "Input <" << uri << "> does not exist" << std::endl;
      74           0 :         std::exit(EXIT_FAILURE);
      75           0 :     } catch (unoidl::FileFormatException & e) {
      76             :         std::cerr
      77           0 :             << "Cannot read input <" << uri << ">: " << e.getDetail()
      78           0 :             << std::endl;
      79           0 :         std::exit(EXIT_FAILURE);
      80             :     }
      81             : }
      82             : 
      83       50362 : sal_uInt64 getOffset(osl::File & file) {
      84             :     sal_uInt64 off;
      85       50362 :     osl::FileBase::RC e = file.getPos(off);
      86       50362 :     if (e != osl::FileBase::E_None) {
      87             :         std::cerr
      88           0 :             << "Cannot determine current position in <" << file.getURL()
      89           0 :             << ">, error code " << +e << std::endl;
      90           0 :         std::exit(EXIT_FAILURE);
      91             :     }
      92       50362 :     return off;
      93             : }
      94             : 
      95      193009 : void write(osl::File & file, void const * buffer, sal_uInt64 size) {
      96             :     sal_uInt64 n;
      97      193009 :     osl::FileBase::RC e = file.write(buffer, size, n);
      98      193009 :     if (e != osl::FileBase::E_None) {
      99             :         std::cerr
     100           0 :             << "Cannot write to <" << file.getURL() << ">, error code " << +e
     101           0 :             << std::endl;
     102           0 :         std::exit(EXIT_FAILURE);
     103             :     }
     104      193009 :     if (n != size) {
     105             :         std::cerr
     106           0 :             << "Bad write of " << n << " instead of " << size << " bytes to <"
     107           0 :             << file.getURL() << '>' << std::endl;
     108           0 :         std::exit(EXIT_FAILURE);
     109             :     }
     110      193009 : }
     111             : 
     112       26651 : void write8(osl::File & file, sal_uInt64 value) {
     113       26651 :     if (value > 0xFF) {
     114             :         std::cerr
     115           0 :             << "Cannot write value >= 2^8; input is too large" << std::endl;
     116           0 :         std::exit(EXIT_FAILURE);
     117             :     }
     118             :     unsigned char buf[1];
     119       26651 :     buf[0] = value & 0xFF;
     120       26651 :     write(file, buf, SAL_N_ELEMENTS(buf));
     121       26651 : }
     122             : 
     123        5150 : void write16(osl::File & file, sal_uInt64 value) {
     124        5150 :     if (value > 0xFFFF) {
     125             :         std::cerr
     126           0 :             << "Cannot write value >= 2^16; input is too large" << std::endl;
     127           0 :         std::exit(EXIT_FAILURE);
     128             :     }
     129             :     unsigned char buf[2];
     130        5150 :     buf[0] = value & 0xFF;
     131        5150 :     buf[1] = (value >> 8) & 0xFF;
     132        5150 :     write(file, buf, SAL_N_ELEMENTS(buf));
     133        5150 : }
     134             : 
     135      128453 : void write32(osl::File & file, sal_uInt64 value) {
     136      128453 :     if (value > 0xFFFFFFFF) {
     137             :         std::cerr
     138           0 :             << "Cannot write value >= 2^32; input is too large" << std::endl;
     139           0 :         std::exit(EXIT_FAILURE);
     140             :     }
     141             :     unsigned char buf[4];
     142      128453 :     buf[0] = value & 0xFF;
     143      128453 :     buf[1] = (value >> 8) & 0xFF;
     144      128453 :     buf[2] = (value >> 16) & 0xFF;
     145      128453 :     buf[3] = (value >> 24) & 0xFF;
     146      128453 :     write(file, buf, SAL_N_ELEMENTS(buf));
     147      128453 : }
     148             : 
     149          33 : void write64(osl::File & file, sal_uInt64 value) {
     150             :     unsigned char buf[8];
     151          33 :     buf[0] = value & 0xFF;
     152          33 :     buf[1] = (value >> 8) & 0xFF;
     153          33 :     buf[2] = (value >> 16) & 0xFF;
     154          33 :     buf[3] = (value >> 24) & 0xFF;
     155          33 :     buf[4] = (value >> 32) & 0xFF;
     156          33 :     buf[5] = (value >> 40) & 0xFF;
     157          33 :     buf[6] = (value >> 48) & 0xFF;
     158          33 :     buf[7] = (value >> 56) & 0xFF;
     159          33 :     write(file, buf, SAL_N_ELEMENTS(buf));
     160          33 : }
     161             : 
     162          20 : void writeIso60599Binary32(osl::File & file, float value) {
     163             :     union {
     164             :         unsigned char buf[4];
     165             :         float f; // assuming float is ISO 60599 binary32
     166             :     } sa;
     167          20 :     sa.f = value;
     168             : #if defined OSL_BIGENDIAN
     169             :     std::swap(sa.buf[0], sa.buf[3]);
     170             :     std::swap(sa.buf[1], sa.buf[2]);
     171             : #endif
     172          20 :     write(file, sa.buf, SAL_N_ELEMENTS(sa.buf));
     173          20 : }
     174             : 
     175           0 : void writeIso60599Binary64(osl::File & file, double value) {
     176             :     union {
     177             :         unsigned char buf[8];
     178             :         float d; // assuming double is ISO 60599 binary64
     179             :     } sa;
     180           0 :     sa.d = value;
     181             : #if defined OSL_BIGENDIAN
     182             :     std::swap(sa.buf[0], sa.buf[7]);
     183             :     std::swap(sa.buf[1], sa.buf[6]);
     184             :     std::swap(sa.buf[2], sa.buf[5]);
     185             :     std::swap(sa.buf[3], sa.buf[4]);
     186             : #endif
     187           0 :     write(file, sa.buf, SAL_N_ELEMENTS(sa.buf));
     188           0 : }
     189             : 
     190       67885 : OString toAscii(OUString const & name) {
     191       67885 :     OString ascii;
     192       67885 :     if (!name.convertToString(
     193             :             &ascii, RTL_TEXTENCODING_ASCII_US,
     194             :             (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
     195       67885 :              | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
     196             :     {
     197             :         std::cerr
     198           0 :             << "Cannot convert \"" << name << "\" to US ASCII" << std::endl;
     199           0 :         std::exit(EXIT_FAILURE);
     200             :     }
     201       67885 :     return ascii;
     202             : }
     203             : 
     204         260 : OString toUtf8(OUString const & string) {
     205         260 :     OString ascii;
     206         260 :     if (!string.convertToString(
     207             :             &ascii, RTL_TEXTENCODING_UTF8,
     208             :             (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
     209         260 :              | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
     210             :     {
     211             :         std::cerr
     212           0 :             << "Cannot convert \"" << string << "\" to UTF-8" << std::endl;
     213           0 :         std::exit(EXIT_FAILURE);
     214             :     }
     215         260 :     return ascii;
     216             : }
     217             : 
     218       17660 : sal_uInt64 writeNulName(osl::File & file, OUString const & name) {
     219       17660 :     OString ascii(toAscii(name));
     220       17660 :     if (ascii.indexOf('\0') != -1) {
     221             :         std::cerr
     222           0 :             << "Name \"" << ascii << "\" contains NUL characters" << std::endl;
     223           0 :         std::exit(EXIT_FAILURE);
     224             :     }
     225       17660 :     sal_uInt64 off = getOffset(file);
     226       17660 :     write(file, ascii.getStr(), ascii.getLength() + 1);
     227       17660 :     return off;
     228             : }
     229             : 
     230       50485 : void writeIdxString(osl::File & file, OString const & string) {
     231       50485 :     static std::map< OString, sal_uInt64 > reuse;
     232       50485 :     std::map< OString, sal_uInt64 >::iterator i(reuse.find(string));
     233       50485 :     if (i == reuse.end()) {
     234       15026 :         reuse.insert(std::make_pair(string, getOffset(file)));
     235             :         assert(
     236             :             (static_cast< sal_uInt64 >(string.getLength()) & 0x80000000) == 0);
     237       15026 :         write32(file, static_cast< sal_uInt64 >(string.getLength()));
     238       15026 :         write(file, string.getStr(), string.getLength());
     239             :     } else {
     240       35459 :         if ((i->second & 0x80000000) != 0) {
     241             :             std::cerr
     242           0 :                 << "Cannot write index 0x" << std::hex << i->second << std::dec
     243           0 :                 << " of \"" << string << "\"; input is too large" << std::endl;
     244           0 :             std::exit(EXIT_FAILURE);
     245             :         }
     246       35459 :         write32(file, i->second | 0x80000000);
     247             :     }
     248       50485 : }
     249             : 
     250       50225 : void writeIdxName(osl::File & file, OUString const & name) {
     251       50225 :     writeIdxString(file, toAscii(name));
     252       50225 : }
     253             : 
     254       36130 : void writeAnnotations(
     255             :     osl::File & file, bool annotate,
     256             :     std::vector< OUString > const & annotations)
     257             : {
     258             :     assert(annotate || annotations.empty());
     259       36130 :     if (annotate) {
     260        1309 :         write32(file, annotations.size());
     261             :             // overflow from std::vector::size_type -> sal_uInt64 is unrealistic
     262        4707 :         for (std::vector< OUString >::const_iterator i(annotations.begin());
     263        3138 :              i != annotations.end(); ++i)
     264             :         {
     265         260 :             writeIdxString(file, toUtf8(*i));
     266             :         }
     267             :     }
     268       36130 : }
     269             : 
     270        5685 : void writeKind(
     271             :     osl::File & file,
     272             :     rtl::Reference< unoidl::PublishableEntity > const & entity,
     273             :     bool annotated, bool flag = false)
     274             : {
     275             :     assert(entity.is());
     276        5685 :     sal_uInt64 v = entity->getSort();
     277        5685 :     if (entity->isPublished()) {
     278        2691 :         v |= 0x80;
     279             :     }
     280        5685 :     if (annotated) {
     281         212 :         v |= 0x40;
     282             :     }
     283        5685 :     if (flag) {
     284         585 :         v |= 0x20;
     285             :     }
     286        5685 :     write8(file, v);
     287        5685 : }
     288             : 
     289       29290 : struct Item {
     290        5858 :     explicit Item(rtl::Reference< unoidl::Entity > const & theEntity):
     291        5858 :         entity(theEntity), nameOffset(0), dataOffset(0)
     292        5858 :     {}
     293             : 
     294             :     rtl::Reference< unoidl::Entity > entity;
     295             :     sal_uInt64 nameOffset;
     296             :     sal_uInt64 dataOffset;
     297             : };
     298             : 
     299       59010 : struct ConstItem {
     300       11802 :     ConstItem(
     301             :         unoidl::ConstantValue const & theConstant,
     302             :         std::vector< OUString > const & theAnnotations):
     303             :         constant(theConstant), annotations(theAnnotations), nameOffset(0),
     304       11802 :         dataOffset(0)
     305       11802 :     {}
     306             : 
     307             :     unoidl::ConstantValue constant;
     308             :     std::vector< OUString > annotations;
     309             :     sal_uInt64 nameOffset;
     310             :     sal_uInt64 dataOffset;
     311             : };
     312             : 
     313         181 : sal_uInt64 writeMap(
     314             :     osl::File & file, rtl::Reference< unoidl::MapCursor > const & cursor,
     315             :     std::size_t * rootSize)
     316             : {
     317             :     assert(cursor.is());
     318         181 :     std::map< OUString, Item > map;
     319             :     for (;;) {
     320        6039 :         OUString name;
     321       11897 :         rtl::Reference< unoidl::Entity > ent(cursor->getNext(&name));
     322        6039 :         if (!ent.is()) {
     323         181 :             break;
     324             :         }
     325        5858 :         if (!map.insert(std::make_pair(name, Item(ent))).second) {
     326           0 :             std::cout << "Duplicate name \"" << name << '"' << std::endl;
     327           0 :             std::exit(EXIT_FAILURE);
     328             :         }
     329        5858 :     }
     330        6039 :     for (std::map< OUString, Item >::iterator i(map.begin()); i != map.end();
     331             :          ++i)
     332             :     {
     333        5858 :         switch (i->second.entity->getSort()) {
     334             :         case unoidl::Entity::SORT_MODULE:
     335             :             {
     336             :                 rtl::Reference< unoidl::ModuleEntity > ent2(
     337             :                     static_cast< unoidl::ModuleEntity * >(
     338         173 :                         i->second.entity.get()));
     339         173 :                 i->second.dataOffset = writeMap(file, ent2->createCursor(), 0);
     340         173 :                 break;
     341             :             }
     342             :         case unoidl::Entity::SORT_ENUM_TYPE:
     343             :             {
     344             :                 rtl::Reference< unoidl::EnumTypeEntity > ent2(
     345             :                     static_cast< unoidl::EnumTypeEntity * >(
     346         196 :                         i->second.entity.get()));
     347         196 :                 bool ann = !ent2->getAnnotations().empty();
     348        4416 :                 for (std::vector< unoidl::EnumTypeEntity::Member >::
     349         196 :                          const_iterator j(ent2->getMembers().begin());
     350        4386 :                      !ann && j != ent2->getMembers().end(); ++j)
     351             :                 {
     352        1271 :                     ann = !j->annotations.empty();
     353             :                 }
     354         196 :                 i->second.dataOffset = getOffset(file);
     355         196 :                 writeKind(file, ent2.get(), ann);
     356         196 :                 write32(file, ent2->getMembers().size());
     357        4548 :                 for (std::vector< unoidl::EnumTypeEntity::Member >::
     358         196 :                          const_iterator j(ent2->getMembers().begin());
     359        3032 :                      j != ent2->getMembers().end(); ++j)
     360             :                 {
     361        1320 :                     writeIdxName(file, j->name);
     362        1320 :                     write32(file, static_cast< sal_uInt32 >(j->value));
     363        1320 :                     writeAnnotations(file, ann, j->annotations);
     364             :                 }
     365         196 :                 writeAnnotations(file, ann, ent2->getAnnotations());
     366         196 :                 break;
     367             :             }
     368             :         case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE:
     369             :             {
     370             :                 rtl::Reference< unoidl::PlainStructTypeEntity > ent2(
     371             :                     static_cast< unoidl::PlainStructTypeEntity * >(
     372         407 :                         i->second.entity.get()));
     373         407 :                 bool ann = !ent2->getAnnotations().empty();
     374        5430 :                 for (std::vector< unoidl::PlainStructTypeEntity::Member >::
     375         407 :                          const_iterator j(ent2->getDirectMembers().begin());
     376        5400 :                      !ann && j != ent2->getDirectMembers().end(); ++j)
     377             :                 {
     378        1398 :                     ann = !j->annotations.empty();
     379             :                 }
     380         407 :                 i->second.dataOffset = getOffset(file);
     381             :                 writeKind(
     382         407 :                     file, ent2.get(), ann, !ent2->getDirectBase().isEmpty());
     383         407 :                 if (!ent2->getDirectBase().isEmpty()) {
     384         103 :                     writeIdxName(file, ent2->getDirectBase());
     385             :                 }
     386         407 :                 write32(file, ent2->getDirectMembers().size());
     387        5580 :                 for (std::vector< unoidl::PlainStructTypeEntity::Member >::
     388         407 :                          const_iterator j(ent2->getDirectMembers().begin());
     389        3720 :                      j != ent2->getDirectMembers().end(); ++j)
     390             :                 {
     391        1453 :                     writeIdxName(file, j->name);
     392        1453 :                     writeIdxName(file, j->type);
     393        1453 :                     writeAnnotations(file, ann, j->annotations);
     394             :                 }
     395         407 :                 writeAnnotations(file, ann, ent2->getAnnotations());
     396         407 :                 break;
     397             :             }
     398             :         case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE:
     399             :             {
     400             :                 rtl::Reference< unoidl::PolymorphicStructTypeTemplateEntity >
     401             :                     ent2(
     402             :                         static_cast<
     403             :                         unoidl::PolymorphicStructTypeTemplateEntity * >(
     404           8 :                             i->second.entity.get()));
     405           8 :                 bool ann = !ent2->getAnnotations().empty();
     406          66 :                 for (std::vector<
     407             :                          unoidl::PolymorphicStructTypeTemplateEntity::Member >::
     408             :                          const_iterator j(
     409           8 :                              ent2->getMembers().begin());
     410          66 :                      !ann && j != ent2->getMembers().end(); ++j)
     411             :                 {
     412          14 :                     ann = !j->annotations.empty();
     413             :                 }
     414           8 :                 i->second.dataOffset = getOffset(file);
     415           8 :                 writeKind(file, ent2.get(), ann);
     416           8 :                 write32(file, ent2->getTypeParameters().size());
     417          57 :                 for (std::vector< OUString >::const_iterator j(
     418           8 :                          ent2->getTypeParameters().begin());
     419          38 :                      j != ent2->getTypeParameters().end(); ++j)
     420             :                 {
     421          11 :                     writeIdxName(file, *j);
     422             :                 }
     423           8 :                 write32(file, ent2->getMembers().size());
     424          66 :                 for (std::vector<
     425             :                          unoidl::PolymorphicStructTypeTemplateEntity::Member >::
     426             :                          const_iterator j(
     427           8 :                              ent2->getMembers().begin());
     428          44 :                      j != ent2->getMembers().end(); ++j)
     429             :                 {
     430          14 :                     sal_uInt64 f = 0;
     431          14 :                     if (j->parameterized) {
     432           9 :                         f |= 0x01;
     433             :                     }
     434          14 :                     write8(file, f);
     435          14 :                     writeIdxName(file, j->name);
     436          14 :                     writeIdxName(file, j->type);
     437          14 :                     writeAnnotations(file, ann, j->annotations);
     438             :                 }
     439           8 :                 writeAnnotations(file, ann, ent2->getAnnotations());
     440           8 :                 break;
     441             :             }
     442             :         case unoidl::Entity::SORT_EXCEPTION_TYPE:
     443             :             {
     444             :                 rtl::Reference< unoidl::ExceptionTypeEntity > ent2(
     445             :                     static_cast< unoidl::ExceptionTypeEntity * >(
     446         250 :                         i->second.entity.get()));
     447         250 :                 bool ann = !ent2->getAnnotations().empty();
     448        1229 :                 for (std::vector< unoidl::ExceptionTypeEntity::Member >::
     449         250 :                          const_iterator j(ent2->getDirectMembers().begin());
     450        1225 :                      !ann && j != ent2->getDirectMembers().end(); ++j)
     451             :                 {
     452         159 :                     ann = !j->annotations.empty();
     453             :                 }
     454         250 :                 i->second.dataOffset = getOffset(file);
     455             :                 writeKind(
     456         250 :                     file, ent2.get(), ann, !ent2->getDirectBase().isEmpty());
     457         250 :                 if (!ent2->getDirectBase().isEmpty()) {
     458         249 :                     writeIdxName(file, ent2->getDirectBase());
     459             :                 }
     460         250 :                 write32(file, ent2->getDirectMembers().size());
     461        1230 :                 for (std::vector< unoidl::ExceptionTypeEntity::Member >::
     462         250 :                          const_iterator j(ent2->getDirectMembers().begin());
     463         820 :                      j != ent2->getDirectMembers().end(); ++j)
     464             :                 {
     465         160 :                     writeIdxName(file, j->name);
     466         160 :                     writeIdxName(file, j->type);
     467         160 :                     writeAnnotations(file, ann, j->annotations);
     468             :                 }
     469         250 :                 writeAnnotations(file, ann, ent2->getAnnotations());
     470         250 :                 break;
     471             :             }
     472             :         case unoidl::Entity::SORT_INTERFACE_TYPE:
     473             :             {
     474             :                 rtl::Reference< unoidl::InterfaceTypeEntity > ent2(
     475             :                     static_cast< unoidl::InterfaceTypeEntity * >(
     476        1901 :                         i->second.entity.get()));
     477        1901 :                 bool ann = !ent2->getAnnotations().empty();
     478       11956 :                 for (std::vector< unoidl::AnnotatedReference >::const_iterator
     479        1901 :                          j(ent2->getDirectMandatoryBases().begin());
     480       11762 :                      !ann && j != ent2->getDirectMandatoryBases().end(); ++j)
     481             :                 {
     482        2052 :                     ann = !j->annotations.empty();
     483             :                 }
     484        5827 :                 for (std::vector< unoidl::AnnotatedReference >::const_iterator
     485        1901 :                          j(ent2->getDirectOptionalBases().begin());
     486        5633 :                      !ann && j != ent2->getDirectOptionalBases().end(); ++j)
     487             :                 {
     488           9 :                     ann = !j->annotations.empty();
     489             :                 }
     490        9371 :                 for (std::vector< unoidl::InterfaceTypeEntity::Attribute >::
     491        1901 :                          const_iterator j(ent2->getDirectAttributes().begin());
     492        9175 :                      !ann && j != ent2->getDirectAttributes().end(); ++j)
     493             :                 {
     494        1190 :                     ann = !j->annotations.empty();
     495             :                 }
     496       23734 :                 for (std::vector< unoidl::InterfaceTypeEntity::Method >::
     497        1901 :                          const_iterator j(ent2->getDirectMethods().begin());
     498       23528 :                      !ann && j != ent2->getDirectMethods().end(); ++j)
     499             :                 {
     500        5976 :                     ann = !j->annotations.empty();
     501             :                 }
     502        1901 :                 i->second.dataOffset = getOffset(file);
     503        1901 :                 writeKind(file, ent2.get(), ann);
     504        1901 :                 write32(file, ent2->getDirectMandatoryBases().size());
     505       12153 :                 for (std::vector< unoidl::AnnotatedReference >::const_iterator
     506        1901 :                          j(ent2->getDirectMandatoryBases().begin());
     507        8102 :                      j != ent2->getDirectMandatoryBases().end(); ++j)
     508             :                 {
     509        2150 :                     writeIdxName(file, j->name);
     510        2150 :                     writeAnnotations(file, ann, j->annotations);
     511             :                 }
     512        1901 :                 write32(file, ent2->getDirectOptionalBases().size());
     513        5730 :                 for (std::vector< unoidl::AnnotatedReference >::const_iterator
     514        1901 :                          j(ent2->getDirectOptionalBases().begin());
     515        3820 :                      j != ent2->getDirectOptionalBases().end(); ++j)
     516             :                 {
     517           9 :                     writeIdxName(file, j->name);
     518           9 :                     writeAnnotations(file, ann, j->annotations);
     519             :                 }
     520        1901 :                 write32(file, ent2->getDirectAttributes().size());
     521        9288 :                 for (std::vector< unoidl::InterfaceTypeEntity::Attribute >::
     522        1901 :                          const_iterator j(ent2->getDirectAttributes().begin());
     523        6192 :                      j != ent2->getDirectAttributes().end(); ++j)
     524             :                 {
     525        1195 :                     sal_uInt64 f = 0;
     526        1195 :                     if (j->bound) {
     527         153 :                         f |= 0x01;
     528             :                     }
     529        1195 :                     if (j->readOnly) {
     530         269 :                         f |= 0x02;
     531             :                     }
     532        1195 :                     write8(file, f);
     533        1195 :                     writeIdxName(file, j->name);
     534        1195 :                     writeIdxName(file, j->type);
     535        1195 :                     write32(file, j->getExceptions.size());
     536        3846 :                     for (std::vector< OUString >::const_iterator k(
     537        1195 :                              j->getExceptions.begin());
     538        2564 :                          k != j->getExceptions.end(); ++k)
     539             :                     {
     540          87 :                         writeIdxName(file, *k);
     541             :                     }
     542        1195 :                     if (!j->readOnly) {
     543         926 :                         write32(file, j->setExceptions.size());
     544        3135 :                         for (std::vector< OUString >::const_iterator k(
     545         926 :                                  j->setExceptions.begin());
     546        2090 :                              k != j->setExceptions.end(); ++k)
     547             :                         {
     548         119 :                             writeIdxName(file, *k);
     549             :                         }
     550             :                     }
     551        1195 :                     writeAnnotations(file, ann, j->annotations);
     552             :                 }
     553        1901 :                 write32(file, ent2->getDirectMethods().size());
     554       24624 :                 for (std::vector< unoidl::InterfaceTypeEntity::Method >::
     555        1901 :                          const_iterator j(ent2->getDirectMethods().begin());
     556       16416 :                      j != ent2->getDirectMethods().end(); ++j)
     557             :                 {
     558        6307 :                     writeIdxName(file, j->name);
     559        6307 :                     writeIdxName(file, j->returnType);
     560        6307 :                     write32(file, j->parameters.size());
     561       40029 :                     for (std::vector<
     562             :                              unoidl::InterfaceTypeEntity::Method::Parameter >::
     563        6307 :                              const_iterator k(j->parameters.begin());
     564       26686 :                          k != j->parameters.end(); ++k)
     565             :                     {
     566        7036 :                         write8(file, k->direction);
     567        7036 :                         writeIdxName(file, k->name);
     568        7036 :                         writeIdxName(file, k->type);
     569             :                     }
     570        6307 :                     write32(file, j->exceptions.size());
     571       27744 :                     for (std::vector< OUString >::const_iterator k(
     572        6307 :                              j->exceptions.begin());
     573       18496 :                          k != j->exceptions.end(); ++k)
     574             :                     {
     575        2941 :                         writeIdxName(file, *k);
     576             :                     }
     577        6307 :                     writeAnnotations(file, ann, j->annotations);
     578             :                 }
     579        1901 :                 writeAnnotations(file, ann, ent2->getAnnotations());
     580        1901 :                 break;
     581             :             }
     582             :         case unoidl::Entity::SORT_TYPEDEF:
     583             :             {
     584             :                 rtl::Reference< unoidl::TypedefEntity > ent2(
     585             :                     static_cast< unoidl::TypedefEntity * >(
     586          56 :                         i->second.entity.get()));
     587          56 :                 bool ann = !ent2->getAnnotations().empty();
     588          56 :                 i->second.dataOffset = getOffset(file);
     589          56 :                 writeKind(file, ent2.get(), ann);
     590          56 :                 writeIdxName(file, ent2->getType());
     591          56 :                 writeAnnotations(file, ann, ent2->getAnnotations());
     592          56 :                 break;
     593             :             }
     594             :         case unoidl::Entity::SORT_CONSTANT_GROUP:
     595             :             {
     596             :                 rtl::Reference< unoidl::ConstantGroupEntity > ent2(
     597             :                     static_cast< unoidl::ConstantGroupEntity * >(
     598        1182 :                         i->second.entity.get()));
     599        2364 :                 std::map< OUString, ConstItem > cmap;
     600       38952 :                 for (std::vector< unoidl::ConstantGroupEntity::Member >::
     601        1182 :                          const_iterator j(ent2->getMembers().begin());
     602       25968 :                      j != ent2->getMembers().end(); ++j)
     603             :                 {
     604       23604 :                     if (!cmap.insert(
     605             :                             std::make_pair(
     606       23604 :                                 j->name, ConstItem(j->value, j->annotations))).
     607       23604 :                         second)
     608             :                     {
     609             :                         std::cout
     610           0 :                             << "Duplicate constant group member name \""
     611           0 :                             << j->name << '"' << std::endl;
     612           0 :                         std::exit(EXIT_FAILURE);
     613             :                     }
     614             :                 }
     615       38952 :                 for (std::map< OUString, ConstItem >::iterator j(cmap.begin());
     616       25968 :                      j != cmap.end(); ++j)
     617             :                 {
     618       11802 :                     j->second.dataOffset = getOffset(file);
     619       11802 :                     sal_uInt64 v = j->second.constant.type;
     620       11802 :                     if (!j->second.annotations.empty()) {
     621          14 :                         v |= 0x80;
     622             :                     }
     623       11802 :                     write8(file, v);
     624       11802 :                     switch (j->second.constant.type) {
     625             :                     case unoidl::ConstantValue::TYPE_BOOLEAN:
     626           0 :                         write8(file, j->second.constant.booleanValue ? 1 : 0);
     627           0 :                         break;
     628             :                     case unoidl::ConstantValue::TYPE_BYTE:
     629             :                         write8(
     630             :                             file,
     631             :                             static_cast< sal_uInt8 >(
     632         248 :                                 j->second.constant.byteValue));
     633         248 :                         break;
     634             :                     case unoidl::ConstantValue::TYPE_SHORT:
     635             :                         write16(
     636             :                             file,
     637             :                             static_cast< sal_uInt16 >(
     638        2046 :                                 j->second.constant.shortValue));
     639        2046 :                         break;
     640             :                     case unoidl::ConstantValue::TYPE_UNSIGNED_SHORT:
     641           2 :                         write16(file, j->second.constant.unsignedShortValue);
     642           2 :                         break;
     643             :                     case unoidl::ConstantValue::TYPE_LONG:
     644             :                         write32(
     645             :                             file,
     646             :                             static_cast< sal_uInt32 >(
     647        9451 :                                 j->second.constant.longValue));
     648        9451 :                         break;
     649             :                     case unoidl::ConstantValue::TYPE_UNSIGNED_LONG:
     650           2 :                         write32(file, j->second.constant.unsignedLongValue);
     651           2 :                         break;
     652             :                     case unoidl::ConstantValue::TYPE_HYPER:
     653             :                         write64(
     654             :                             file,
     655             :                             static_cast< sal_uInt64 >(
     656          31 :                                 j->second.constant.hyperValue));
     657          31 :                         break;
     658             :                     case unoidl::ConstantValue::TYPE_UNSIGNED_HYPER:
     659           2 :                         write64(file, j->second.constant.unsignedHyperValue);
     660           2 :                         break;
     661             :                     case unoidl::ConstantValue::TYPE_FLOAT:
     662             :                         writeIso60599Binary32(
     663          20 :                             file, j->second.constant.floatValue);
     664          20 :                         break;
     665             :                     case unoidl::ConstantValue::TYPE_DOUBLE:
     666             :                         writeIso60599Binary64(
     667           0 :                             file, j->second.constant.doubleValue);
     668           0 :                         break;
     669             :                     default:
     670           0 :                         for (;;) { std::abort(); } // this cannot happen
     671             :                     }
     672             :                     writeAnnotations(
     673       11802 :                         file, !j->second.annotations.empty(),
     674       23604 :                         j->second.annotations);
     675             :                 }
     676       38952 :                 for (std::map< OUString, ConstItem >::iterator j(
     677        1182 :                          cmap.begin());
     678       25968 :                      j != cmap.end(); ++j)
     679             :                 {
     680       11802 :                     j->second.nameOffset = writeNulName(file, j->first);
     681             :                 }
     682        1182 :                 bool ann = !ent2->getAnnotations().empty();
     683        1182 :                 i->second.dataOffset = getOffset(file);
     684        1182 :                 writeKind(file, ent2.get(), ann);
     685        1182 :                 write32(file, cmap.size());
     686             :                     // overflow from std::map::size_type -> sal_uInt64 is
     687             :                     // unrealistic
     688       38952 :                 for (std::map< OUString, ConstItem >::iterator j(
     689        1182 :                          cmap.begin());
     690       25968 :                      j != cmap.end(); ++j)
     691             :                 {
     692       11802 :                     write32(file, j->second.nameOffset);
     693       11802 :                     write32(file, j->second.dataOffset);
     694             :                 }
     695        1182 :                 writeAnnotations(file, ann, ent2->getAnnotations());
     696        2364 :                 break;
     697             :             }
     698             :         case unoidl::Entity::SORT_SINGLE_INTERFACE_BASED_SERVICE:
     699             :             {
     700             :                 rtl::Reference< unoidl::SingleInterfaceBasedServiceEntity >
     701             :                     ent2(
     702             :                         static_cast<
     703             :                             unoidl::SingleInterfaceBasedServiceEntity * >(
     704         493 :                                 i->second.entity.get()));
     705         493 :                 bool dfltCtor = ent2->getConstructors().size() == 1
     706         493 :                     && ent2->getConstructors()[0].defaultConstructor;
     707         493 :                 bool ann = !ent2->getAnnotations().empty();
     708         493 :                 if (!dfltCtor) {
     709        1644 :                     for (std::vector<
     710             :                              unoidl::SingleInterfaceBasedServiceEntity::
     711             :                              Constructor >::const_iterator j(
     712         260 :                                  ent2->getConstructors().begin());
     713        1644 :                          !ann && j != ent2->getConstructors().end(); ++j)
     714             :                     {
     715         288 :                         ann = !j->annotations.empty();
     716             :                     }
     717             :                 }
     718         493 :                 i->second.dataOffset = getOffset(file);
     719         493 :                 writeKind(file, ent2.get(), ann, dfltCtor);
     720         493 :                 writeIdxName(file, ent2->getBase());
     721         493 :                 if (!dfltCtor) {
     722         260 :                     write32(file, ent2->getConstructors().size());
     723        1644 :                     for (std::vector<
     724             :                              unoidl::SingleInterfaceBasedServiceEntity::
     725             :                              Constructor >::const_iterator j(
     726         260 :                                  ent2->getConstructors().begin());
     727        1096 :                          j != ent2->getConstructors().end(); ++j)
     728             :                     {
     729         288 :                         if (j->defaultConstructor) {
     730             :                             std::cout
     731           0 :                                 << "Unexpected default constructor \""
     732           0 :                                 << j->name << '"' << std::endl;
     733           0 :                             std::exit(EXIT_FAILURE);
     734             :                         }
     735         288 :                         writeIdxName(file, j->name);
     736         288 :                         write32(file, j->parameters.size());
     737        2358 :                         for (std::vector<
     738             :                                  unoidl::SingleInterfaceBasedServiceEntity::
     739             :                                  Constructor::Parameter >::const_iterator k(
     740         288 :                                      j->parameters.begin());
     741        1572 :                              k != j->parameters.end(); ++k)
     742             :                         {
     743         498 :                             sal_uInt64 f = 0;
     744         498 :                             if (k->rest) {
     745           2 :                                 f |= 0x04;
     746             :                             }
     747         498 :                             write8(file, f);
     748         498 :                             writeIdxName(file, k->name);
     749         498 :                             writeIdxName(file, k->type);
     750             :                         }
     751         288 :                         write32(file, j->exceptions.size());
     752        1041 :                         for (std::vector< OUString >::const_iterator k(
     753         288 :                                  j->exceptions.begin());
     754         694 :                              k != j->exceptions.end(); ++k)
     755             :                         {
     756          59 :                             writeIdxName(file, *k);
     757             :                         }
     758         288 :                         writeAnnotations(file, ann, j->annotations);
     759             :                     }
     760             :                 }
     761         493 :                 writeAnnotations(file, ann, ent2->getAnnotations());
     762         493 :                 break;
     763             :             }
     764             :         case unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE:
     765             :             {
     766             :                 rtl::Reference< unoidl::AccumulationBasedServiceEntity > ent2(
     767             :                     static_cast< unoidl::AccumulationBasedServiceEntity * >(
     768        1027 :                         i->second.entity.get()));
     769        1027 :                 bool ann = !ent2->getAnnotations().empty();
     770        5291 :                 for (std::vector< unoidl::AnnotatedReference >::const_iterator
     771        1027 :                          j(ent2->getDirectMandatoryBaseServices().begin());
     772        5209 :                      !ann && j != ent2->getDirectMandatoryBaseServices().end();
     773             :                      ++j)
     774             :                 {
     775         723 :                     ann = !j->annotations.empty();
     776             :                 }
     777        3306 :                 for (std::vector< unoidl::AnnotatedReference >::const_iterator
     778        1027 :                          j(ent2->getDirectOptionalBaseServices().begin());
     779        3222 :                      !ann && j != ent2->getDirectOptionalBaseServices().end();
     780             :                      ++j)
     781             :                 {
     782          61 :                     ann = !j->annotations.empty();
     783             :                 }
     784        7583 :                 for (std::vector< unoidl::AnnotatedReference >::const_iterator
     785        1027 :                          j(ent2->getDirectMandatoryBaseInterfaces().begin());
     786        2513 :                      (!ann
     787       10008 :                       && j != ent2->getDirectMandatoryBaseInterfaces().end());
     788             :                      ++j)
     789             :                 {
     790        1486 :                     ann = !j->annotations.empty();
     791             :                 }
     792        3944 :                 for (std::vector< unoidl::AnnotatedReference >::const_iterator
     793        1027 :                          j(ent2->getDirectOptionalBaseInterfaces().begin());
     794        3850 :                      !ann && j != ent2->getDirectOptionalBaseInterfaces().end();
     795             :                      ++j)
     796             :                 {
     797         272 :                     ann = !j->annotations.empty();
     798             :                 }
     799       11793 :                 for (std::vector<
     800             :                          unoidl::AccumulationBasedServiceEntity::Property >::
     801             :                          const_iterator j(
     802        1027 :                              ent2->getDirectProperties().begin());
     803       11673 :                      !ann && j != ent2->getDirectProperties().end(); ++j)
     804             :                 {
     805        2884 :                     ann = !j->annotations.empty();
     806             :                 }
     807        1027 :                 i->second.dataOffset = getOffset(file);
     808        1027 :                 writeKind(file, ent2.get(), ann);
     809        1027 :                 write32(file, ent2->getDirectMandatoryBaseServices().size());
     810        5277 :                 for (std::vector< unoidl::AnnotatedReference >::const_iterator
     811        1027 :                          j(ent2->getDirectMandatoryBaseServices().begin());
     812        3518 :                      j != ent2->getDirectMandatoryBaseServices().end(); ++j)
     813             :                 {
     814         732 :                     writeIdxName(file, j->name);
     815         732 :                     writeAnnotations(file, ann, j->annotations);
     816             :                 }
     817        1027 :                 write32(file, ent2->getDirectOptionalBaseServices().size());
     818        3267 :                 for (std::vector< unoidl::AnnotatedReference >::const_iterator
     819        1027 :                          j(ent2->getDirectOptionalBaseServices().begin());
     820        2178 :                      j != ent2->getDirectOptionalBaseServices().end(); ++j)
     821             :                 {
     822          62 :                     writeIdxName(file, j->name);
     823          62 :                     writeAnnotations(file, ann, j->annotations);
     824             :                 }
     825        1027 :                 write32(file, ent2->getDirectMandatoryBaseInterfaces().size());
     826        7761 :                 for (std::vector< unoidl::AnnotatedReference >::const_iterator
     827        1027 :                          j(ent2->getDirectMandatoryBaseInterfaces().begin());
     828        5174 :                      j != ent2->getDirectMandatoryBaseInterfaces().end(); ++j)
     829             :                 {
     830        1560 :                     writeIdxName(file, j->name);
     831        1560 :                     writeAnnotations(file, ann, j->annotations);
     832             :                 }
     833        1027 :                 write32(file, ent2->getDirectOptionalBaseInterfaces().size());
     834        3954 :                 for (std::vector< unoidl::AnnotatedReference >::const_iterator
     835        1027 :                          j(ent2->getDirectOptionalBaseInterfaces().begin());
     836        2636 :                      j != ent2->getDirectOptionalBaseInterfaces().end(); ++j)
     837             :                 {
     838         291 :                     writeIdxName(file, j->name);
     839         291 :                     writeAnnotations(file, ann, j->annotations);
     840             :                 }
     841        1027 :                 write32(file, ent2->getDirectProperties().size());
     842       12387 :                 for (std::vector<
     843             :                          unoidl::AccumulationBasedServiceEntity::Property >::
     844             :                          const_iterator j(
     845        1027 :                              ent2->getDirectProperties().begin());
     846        8258 :                      j != ent2->getDirectProperties().end(); ++j)
     847             :                 {
     848        3102 :                     write16(file, static_cast< sal_uInt16 >(j->attributes));
     849        3102 :                     writeIdxName(file, j->name);
     850        3102 :                     writeIdxName(file, j->type);
     851        3102 :                     writeAnnotations(file, ann, j->annotations);
     852             :                 }
     853        1027 :                 writeAnnotations(file, ann, ent2->getAnnotations());
     854        1027 :                 break;
     855             :             }
     856             :         case unoidl::Entity::SORT_INTERFACE_BASED_SINGLETON:
     857             :             {
     858             :                 rtl::Reference< unoidl::InterfaceBasedSingletonEntity > ent2(
     859             :                     static_cast< unoidl::InterfaceBasedSingletonEntity * >(
     860         164 :                         i->second.entity.get()));
     861         164 :                 bool ann = !ent2->getAnnotations().empty();
     862         164 :                 i->second.dataOffset = getOffset(file);
     863         164 :                 writeKind(file, ent2.get(), ann);
     864         164 :                 writeIdxName(file, ent2->getBase());
     865         164 :                 writeAnnotations(file, ann, ent2->getAnnotations());
     866         164 :                 break;
     867             :             }
     868             :         case unoidl::Entity::SORT_SERVICE_BASED_SINGLETON:
     869             :             {
     870             :                 rtl::Reference< unoidl::ServiceBasedSingletonEntity > ent2(
     871             :                     static_cast< unoidl::ServiceBasedSingletonEntity * >(
     872           1 :                         i->second.entity.get()));
     873           1 :                 bool ann = !ent2->getAnnotations().empty();
     874           1 :                 i->second.dataOffset = getOffset(file);
     875           1 :                 writeKind(file, ent2.get(), ann);
     876           1 :                 writeIdxName(file, ent2->getBase());
     877           1 :                 writeAnnotations(file, ann, ent2->getAnnotations());
     878           1 :                 break;
     879             :             }
     880             :         }
     881             :     }
     882        6039 :     for (std::map< OUString, Item >::iterator i(map.begin()); i != map.end();
     883             :          ++i)
     884             :     {
     885        5858 :         i->second.nameOffset = writeNulName(file, i->first);
     886             :     }
     887         181 :     sal_uInt64 off = getOffset(file);
     888         181 :     if (rootSize == 0) {
     889         173 :         write8(file, 0); // SORT_MODULE
     890         173 :         write32(file, map.size());
     891             :             // overflow from std::map::size_type -> sal_uInt64 is unrealistic
     892             :     } else {
     893           8 :         *rootSize = map.size();
     894             :             // overflow from std::map::size_type -> std::size_t is unrealistic
     895             :     }
     896        6039 :     for (std::map< OUString, Item >::iterator i(map.begin()); i != map.end();
     897             :          ++i)
     898             :     {
     899        5858 :         write32(file, i->second.nameOffset);
     900        5858 :         write32(file, i->second.dataOffset);
     901             :     }
     902         181 :     return off;
     903             : }
     904             : 
     905             : }
     906             : 
     907          16 : SAL_IMPLEMENT_MAIN() {
     908           8 :     sal_uInt32 args = rtl_getAppCommandArgCount();
     909           8 :     if (args < 2) {
     910             :         std::cerr
     911           0 :             << "Usage: reg2unoidl <extra .rdb files> <.rdb file> <unoidl file>"
     912           0 :             << std::endl;
     913           0 :         std::exit(EXIT_FAILURE);
     914             :     }
     915           8 :     rtl::Reference< unoidl::Manager > mgr(new unoidl::Manager);
     916          17 :     for (sal_uInt32 i = 0; i != args - 2; ++i) {
     917           9 :         mgr->addProvider(load(mgr, getArgumentUri(i)));
     918             :     }
     919             :     rtl::Reference< unoidl::Provider > prov(
     920          16 :         load(mgr, getArgumentUri(args - 2)));
     921          16 :     osl::File f(getArgumentUri(args - 1));
     922           8 :     osl::FileBase::RC e = f.open(osl_File_OpenFlag_Write);
     923           8 :     if (e == osl::FileBase::E_NOENT) {
     924           8 :         e = f.open(osl_File_OpenFlag_Write | osl_File_OpenFlag_Create);
     925             :     }
     926           8 :     if (e != osl::FileBase::E_None) {
     927             :         std::cerr
     928           0 :             << "Cannot open <" << f.getURL() << "> for writing, error code "
     929           0 :             << +e << std::endl;
     930           0 :         std::exit(EXIT_FAILURE);
     931             :     }
     932           8 :     write(f, "UNOIDL\xFF\0", 8);
     933           8 :     write32(f, 0); // root map offset
     934           8 :     write32(f, 0); // root map size
     935             :     write(
     936             :         f,
     937           8 :         RTL_CONSTASCII_STRINGPARAM(
     938             :             "\0** Created by LibreOffice " LIBO_VERSION_DOTTED
     939           8 :             " reg2unoidl **\0"));
     940             :     sal_uInt64 off;
     941             :     std::size_t size;
     942             :     try {
     943           8 :         off = writeMap(f, prov->createRootCursor(), &size);
     944           0 :     } catch (unoidl::FileFormatException & e1) {
     945             :         std::cerr
     946           0 :             << "Bad input <" << e1.getUri() << ">: " << e1.getDetail()
     947           0 :             << std::endl;
     948           0 :         std::exit(EXIT_FAILURE);
     949             :     }
     950           8 :     e = f.setSize(getOffset(f)); // truncate in case it already existed
     951           8 :     if (e != osl::FileBase::E_None) {
     952             :         std::cerr
     953           0 :             << "Cannot set size of <" << f.getURL() << ">, error code " << +e
     954           0 :             << std::endl;
     955           0 :         std::exit(EXIT_FAILURE);
     956             :     }
     957           8 :     e = f.setPos(osl_Pos_Absolut, 8);
     958           8 :     if (e != osl::FileBase::E_None) {
     959             :         std::cerr
     960           0 :             << "Cannot rewind current position in <" << f.getURL()
     961           0 :             << ">, error code " << +e << std::endl;
     962           0 :         std::exit(EXIT_FAILURE);
     963             :     }
     964           8 :     write32(f, off);
     965           8 :     write32(f, size);
     966             :         // overflow from std::map::size_type -> sal_uInt64 is unrealistic
     967           8 :     e = f.close();
     968           8 :     if (e != osl::FileBase::E_None) {
     969             :         std::cerr
     970           0 :             << "Cannot close <" << f.getURL() << "> after writing, error code "
     971           0 :             << +e << std::endl;
     972           0 :         std::exit(EXIT_FAILURE);
     973             :     }
     974          16 :     return EXIT_SUCCESS;
     975          24 : }
     976             : 
     977             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10