LCOV - code coverage report
Current view: top level - configmgr/source - xcuparser.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 381 503 75.7 %
Date: 2012-08-25 Functions: 19 19 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 529 1494 35.4 %

           Branch data     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                 :            :  * This file incorporates work covered by the following license notice:
      10                 :            :  *
      11                 :            :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12                 :            :  *   contributor license agreements. See the NOTICE file distributed
      13                 :            :  *   with this work for additional information regarding copyright
      14                 :            :  *   ownership. The ASF licenses this file to you under the Apache
      15                 :            :  *   License, Version 2.0 (the "License"); you may not use this file
      16                 :            :  *   except in compliance with the License. You may obtain a copy of
      17                 :            :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18                 :            :  */
      19                 :            : 
      20                 :            : #include "sal/config.h"
      21                 :            : 
      22                 :            : #include <algorithm>
      23                 :            : #include <cassert>
      24                 :            : 
      25                 :            : #include "com/sun/star/uno/Any.hxx"
      26                 :            : #include "com/sun/star/uno/Reference.hxx"
      27                 :            : #include "com/sun/star/uno/RuntimeException.hpp"
      28                 :            : #include "com/sun/star/uno/XInterface.hpp"
      29                 :            : #include "rtl/oustringostreaminserter.hxx"
      30                 :            : #include "rtl/ref.hxx"
      31                 :            : #include "rtl/strbuf.hxx"
      32                 :            : #include "rtl/string.h"
      33                 :            : #include "rtl/string.hxx"
      34                 :            : #include "rtl/ustring.h"
      35                 :            : #include "rtl/ustring.hxx"
      36                 :            : #include "sal/log.hxx"
      37                 :            : #include "xmlreader/span.hxx"
      38                 :            : #include "xmlreader/xmlreader.hxx"
      39                 :            : 
      40                 :            : #include "data.hxx"
      41                 :            : #include "localizedpropertynode.hxx"
      42                 :            : #include "localizedvaluenode.hxx"
      43                 :            : #include "groupnode.hxx"
      44                 :            : #include "modifications.hxx"
      45                 :            : #include "node.hxx"
      46                 :            : #include "nodemap.hxx"
      47                 :            : #include "parsemanager.hxx"
      48                 :            : #include "partial.hxx"
      49                 :            : #include "path.hxx"
      50                 :            : #include "propertynode.hxx"
      51                 :            : #include "setnode.hxx"
      52                 :            : #include "xcuparser.hxx"
      53                 :            : #include "xmldata.hxx"
      54                 :            : 
      55                 :            : namespace configmgr {
      56                 :            : 
      57                 :            : namespace {
      58                 :            : 
      59                 :            : namespace css = com::sun::star;
      60                 :            : 
      61                 :            : }
      62                 :            : 
      63                 :      48373 : XcuParser::XcuParser(
      64                 :            :     int layer, Data & data, Partial const * partial,
      65                 :            :     Modifications * broadcastModifications, Additions * additions):
      66                 :            :     valueParser_(layer), data_(data),
      67                 :            :     partial_(partial), broadcastModifications_(broadcastModifications),
      68                 :            :     additions_(additions), recordModifications_(layer == Data::NO_LAYER),
      69                 :            :     trackPath_(
      70                 :            :         partial_ != 0 || broadcastModifications_ != 0 || additions_ != 0 ||
      71 [ +  - ][ +  - ]:      48373 :         recordModifications_)
         [ +  - ][ +  - ]
         [ +  + ][ +  - ]
         [ +  - ][ +  - ]
      72                 :      48373 : {}
      73                 :            : 
      74 [ +  - ][ -  + ]:      96746 : XcuParser::~XcuParser() {}
      75                 :            : 
      76                 :   36606731 : xmlreader::XmlReader::Text XcuParser::getTextMode() {
      77                 :   36606731 :     return valueParser_.getTextMode();
      78                 :            : }
      79                 :            : 
      80                 :   15364408 : bool XcuParser::startElement(
      81                 :            :     xmlreader::XmlReader & reader, int nsId, xmlreader::Span const & name)
      82                 :            : {
      83         [ +  + ]:   15364408 :     if (valueParser_.startElement(reader, nsId, name)) {
      84                 :      25944 :         return true;
      85                 :            :     }
      86         [ +  + ]:   15338464 :     if (state_.empty()) {
      87   [ +  -  +  + ]:      96622 :         if (nsId == ParseManager::NAMESPACE_OOR &&
                 [ +  + ]
      88                 :      48311 :             name.equals(RTL_CONSTASCII_STRINGPARAM("component-data")))
      89                 :            :         {
      90                 :      48213 :             handleComponentData(reader);
      91   [ +  -  +  - ]:        196 :         } else if (nsId == ParseManager::NAMESPACE_OOR &&
                 [ +  - ]
      92                 :         98 :                    name.equals(RTL_CONSTASCII_STRINGPARAM("items")))
      93                 :            :         {
      94 [ +  - ][ +  - ]:         98 :             state_.push(State(rtl::Reference< Node >(), false));
                 [ +  - ]
      95                 :            :         } else {
      96                 :            :             throw css::uno::RuntimeException(
      97                 :            :                 (rtl::OUString(
      98                 :            :                     RTL_CONSTASCII_USTRINGPARAM("bad root element <")) +
      99                 :            :                  name.convertFromUtf8() +
     100                 :            :                  rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("> in ")) +
     101                 :            :                  reader.getUrl()),
     102 [ #  # ][ #  # ]:          0 :                 css::uno::Reference< css::uno::XInterface >());
         [ #  # ][ #  # ]
                 [ #  # ]
     103                 :            :         }
     104         [ -  + ]:   15290153 :     } else if (state_.top().ignore) {
     105         [ #  # ]:          0 :         state_.push(State(false));
     106         [ +  + ]:   15290153 :     } else if (!state_.top().node.is()) {
     107   [ +  -  +  - ]:      24824 :         if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
                 [ +  - ]
     108                 :      12412 :             name.equals(RTL_CONSTASCII_STRINGPARAM("item")))
     109                 :            :         {
     110                 :      12412 :             handleItem(reader);
     111                 :            :         } else {
     112                 :            :             throw css::uno::RuntimeException(
     113                 :            :                 (rtl::OUString(
     114                 :            :                     RTL_CONSTASCII_USTRINGPARAM("bad items node member <")) +
     115                 :            :                  name.convertFromUtf8() +
     116                 :            :                  rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("> in ")) +
     117                 :            :                  reader.getUrl()),
     118 [ #  # ][ #  # ]:          0 :                 css::uno::Reference< css::uno::XInterface >());
         [ #  # ][ #  # ]
                 [ #  # ]
     119                 :            :         }
     120                 :            :     } else {
     121   [ +  +  -  +  :   15277741 :         switch (state_.top().node->kind()) {
                +  -  - ]
     122                 :            :         case Node::KIND_PROPERTY:
     123   [ +  -  +  - ]:    8685694 :             if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
                 [ +  - ]
     124                 :    4342847 :                 name.equals(RTL_CONSTASCII_STRINGPARAM("value")))
     125                 :            :             {
     126                 :            :                 handlePropValue(
     127                 :            :                     reader,
     128         [ -  + ]:    4342847 :                     dynamic_cast< PropertyNode * >(state_.top().node.get()));
     129                 :            :             } else {
     130                 :            :                 throw css::uno::RuntimeException(
     131                 :            :                     (rtl::OUString(
     132                 :            :                         RTL_CONSTASCII_USTRINGPARAM(
     133                 :            :                             "bad property node member <")) +
     134                 :            :                      name.convertFromUtf8() +
     135                 :            :                      rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("> in ")) +
     136                 :            :                      reader.getUrl()),
     137 [ #  # ][ #  # ]:          0 :                     css::uno::Reference< css::uno::XInterface >());
         [ #  # ][ #  # ]
                 [ #  # ]
     138                 :            :             }
     139                 :    4342847 :             break;
     140                 :            :         case Node::KIND_LOCALIZED_PROPERTY:
     141   [ +  -  +  - ]:    3621880 :             if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
                 [ +  - ]
     142                 :    1810940 :                 name.equals(RTL_CONSTASCII_STRINGPARAM("value")))
     143                 :            :             {
     144                 :            :                 handleLocpropValue(
     145                 :            :                     reader,
     146                 :            :                     dynamic_cast< LocalizedPropertyNode * >(
     147         [ -  + ]:    1810940 :                         state_.top().node.get()));
     148                 :            :             } else {
     149                 :            :                 throw css::uno::RuntimeException(
     150                 :            :                     (rtl::OUString(
     151                 :            :                         RTL_CONSTASCII_USTRINGPARAM(
     152                 :            :                             "bad localized property node member <")) +
     153                 :            :                      name.convertFromUtf8() +
     154                 :            :                      rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("> in ")) +
     155                 :            :                      reader.getUrl()),
     156 [ #  # ][ #  # ]:          0 :                     css::uno::Reference< css::uno::XInterface >());
         [ #  # ][ #  # ]
                 [ #  # ]
     157                 :            :             }
     158                 :    1810940 :             break;
     159                 :            :         case Node::KIND_LOCALIZED_VALUE:
     160                 :            :             throw css::uno::RuntimeException(
     161                 :            :                 (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("bad member <")) +
     162                 :            :                  name.convertFromUtf8() +
     163                 :            :                  rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("> in ")) +
     164                 :            :                  reader.getUrl()),
     165 [ #  # ][ #  # ]:          0 :                 css::uno::Reference< css::uno::XInterface >());
         [ #  # ][ #  # ]
                 [ #  # ]
     166                 :            :         case Node::KIND_GROUP:
     167   [ +  -  +  + ]:   13212234 :             if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
                 [ +  + ]
     168                 :    6606117 :                 name.equals(RTL_CONSTASCII_STRINGPARAM("prop")))
     169                 :            :             {
     170                 :            :                 handleGroupProp(
     171                 :            :                     reader,
     172         [ -  + ]:    6426494 :                     dynamic_cast< GroupNode * >(state_.top().node.get()));
     173   [ +  -  +  - ]:     359246 :             } else if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
                 [ +  - ]
     174                 :     179623 :                        name.equals(RTL_CONSTASCII_STRINGPARAM("node")))
     175                 :            :             {
     176                 :     179623 :                 handleGroupNode(reader, state_.top().node);
     177                 :            :             } else {
     178                 :            :                 throw css::uno::RuntimeException(
     179                 :            :                     (rtl::OUString(
     180                 :            :                         RTL_CONSTASCII_USTRINGPARAM(
     181                 :            :                             "bad group node member <")) +
     182                 :            :                      name.convertFromUtf8() +
     183                 :            :                      rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("> in ")) +
     184                 :            :                      reader.getUrl()),
     185 [ #  # ][ #  # ]:          0 :                     css::uno::Reference< css::uno::XInterface >());
         [ #  # ][ #  # ]
                 [ #  # ]
     186                 :            :             }
     187                 :    6606117 :             break;
     188                 :            :         case Node::KIND_SET:
     189   [ +  -  +  - ]:    5035674 :             if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
                 [ +  - ]
     190                 :    2517837 :                 name.equals(RTL_CONSTASCII_STRINGPARAM("node")))
     191                 :            :             {
     192                 :            :                 handleSetNode(
     193         [ -  + ]:    2517837 :                     reader, dynamic_cast< SetNode * >(state_.top().node.get()));
     194   [ #  #  #  # ]:          0 :             } else if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
                 [ #  # ]
     195                 :          0 :                        name.equals(RTL_CONSTASCII_STRINGPARAM("prop")))
     196                 :            :             {
     197                 :            :                 SAL_WARN(
     198                 :            :                     "configmgr",
     199                 :            :                     "bad set node <prop> member in \"" << reader.getUrl()
     200                 :            :                         << '"');
     201         [ #  # ]:          0 :                 state_.push(State(true)); // ignored
     202                 :            :             } else {
     203                 :            :                 throw css::uno::RuntimeException(
     204                 :            :                     (rtl::OUString(
     205                 :            :                         RTL_CONSTASCII_USTRINGPARAM("bad set node member <")) +
     206                 :            :                      name.convertFromUtf8() +
     207                 :            :                      rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("> in ")) +
     208                 :            :                      reader.getUrl()),
     209 [ #  # ][ #  # ]:          0 :                     css::uno::Reference< css::uno::XInterface >());
         [ #  # ][ #  # ]
                 [ #  # ]
     210                 :            :             }
     211                 :    2517837 :             break;
     212                 :            :         case Node::KIND_ROOT:
     213                 :            :             assert(false); // this cannot happen
     214                 :          0 :             break;
     215                 :            :         }
     216                 :            :     }
     217                 :   15364408 :     return true;
     218                 :            : }
     219                 :            : 
     220                 :   15364408 : void XcuParser::endElement(xmlreader::XmlReader const &) {
     221 [ +  - ][ +  + ]:   15364408 :     if (valueParser_.endElement()) {
     222                 :   15364408 :         return;
     223                 :            :     }
     224                 :            :     assert(!state_.empty());
     225         [ +  - ]:    9193468 :     bool pop = state_.top().pop;
     226                 :    9193468 :     rtl::Reference< Node > insert;
     227                 :    9193468 :     rtl::OUString name;
     228 [ +  + ][ +  - ]:    9193468 :     if (state_.top().insert) {
     229 [ +  - ][ +  - ]:    2587095 :         insert = state_.top().node;
     230                 :            :         assert(insert.is());
     231         [ +  - ]:    2587095 :         name = state_.top().name;
     232                 :            :     }
     233         [ +  - ]:    9193468 :     state_.pop();
     234         [ +  + ]:    9193468 :     if (insert.is()) {
     235                 :            :         assert(!state_.empty() && state_.top().node.is());
     236 [ +  - ][ +  - ]:    2587095 :         state_.top().node->getMembers()[name] = insert;
         [ +  - ][ +  - ]
     237                 :            :     }
     238 [ +  + ][ +  + ]:    9193468 :     if (pop && !path_.empty()) {
                 [ +  + ]
     239         [ +  - ]:      27902 :         path_.pop_back();
     240                 :            :             // </item> will pop less than <item> pushed, but that is harmless,
     241                 :            :             // as the next <item> will reset path_
     242         [ +  - ]:   15364408 :     }
     243                 :            : }
     244                 :            : 
     245                 :    5879180 : void XcuParser::characters(xmlreader::Span const & text) {
     246                 :    5879180 :     valueParser_.characters(text);
     247                 :    5879180 : }
     248                 :            : 
     249                 :    2592619 : XcuParser::Operation XcuParser::parseOperation(xmlreader::Span const & text) {
     250                 :            :     assert(text.is());
     251         [ -  + ]:    2592619 :     if (text.equals(RTL_CONSTASCII_STRINGPARAM("modify"))) {
     252                 :          0 :         return OPERATION_MODIFY;
     253                 :            :     }
     254         [ +  + ]:    2592619 :     if (text.equals(RTL_CONSTASCII_STRINGPARAM("replace"))) {
     255                 :    2561363 :         return OPERATION_REPLACE;
     256                 :            :     }
     257         [ +  - ]:      31256 :     if (text.equals(RTL_CONSTASCII_STRINGPARAM("fuse"))) {
     258                 :      31256 :         return OPERATION_FUSE;
     259                 :            :     }
     260         [ #  # ]:          0 :     if (text.equals(RTL_CONSTASCII_STRINGPARAM("remove"))) {
     261                 :          0 :         return OPERATION_REMOVE;
     262                 :            :     }
     263                 :            :     throw css::uno::RuntimeException(
     264                 :            :         (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("invalid op ")) +
     265                 :            :          text.convertFromUtf8()),
     266 [ #  # ][ #  # ]:    2592619 :         css::uno::Reference< css::uno::XInterface >());
                 [ #  # ]
     267                 :            : }
     268                 :            : 
     269                 :      48213 : void XcuParser::handleComponentData(xmlreader::XmlReader & reader) {
     270                 :      48213 :     rtl::OStringBuffer buf;
     271         [ +  - ]:      48213 :     buf.append('.');
     272                 :      48213 :     bool hasPackage = false;
     273                 :      48213 :     bool hasName = false;
     274                 :      48213 :     Operation op = OPERATION_MODIFY;
     275                 :      48213 :     bool finalized = false;
     276                 :      96426 :     for (;;) {
     277                 :            :         int attrNsId;
     278                 :     144639 :         xmlreader::Span attrLn;
     279 [ +  + ][ +  - ]:     144639 :         if (!reader.nextAttribute(&attrNsId, &attrLn)) {
     280                 :            :             break;
     281                 :            :         }
     282   [ +  -  +  + ]:     192852 :         if (attrNsId == ParseManager::NAMESPACE_OOR &&
                 [ +  + ]
     283                 :      96426 :             attrLn.equals(RTL_CONSTASCII_STRINGPARAM("package")))
     284                 :            :         {
     285         [ -  + ]:      48213 :             if (hasPackage) {
     286                 :            :                 throw css::uno::RuntimeException(
     287                 :            :                     (rtl::OUString(
     288                 :            :                         RTL_CONSTASCII_USTRINGPARAM(
     289                 :            :                             "multiple component-update package attributes"
     290                 :            :                             " in ")) +
     291                 :            :                      reader.getUrl()),
     292 [ #  # ][ #  # ]:          0 :                     css::uno::Reference< css::uno::XInterface >());
                 [ #  # ]
     293                 :            :             }
     294                 :      48213 :             hasPackage = true;
     295         [ +  - ]:      48213 :             xmlreader::Span s(reader.getAttributeValue(false));
     296         [ +  - ]:      48213 :             buf.insert(0, s.begin, s.length);
     297   [ +  -  +  - ]:      96426 :         } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
                 [ +  - ]
     298                 :      48213 :                    attrLn.equals(RTL_CONSTASCII_STRINGPARAM("name")))
     299                 :            :         {
     300         [ -  + ]:      48213 :             if (hasName) {
     301                 :            :                 throw css::uno::RuntimeException(
     302                 :            :                     (rtl::OUString(
     303                 :            :                         RTL_CONSTASCII_USTRINGPARAM(
     304                 :            :                             "multiple component-update name attributes in ")) +
     305                 :            :                      reader.getUrl()),
     306 [ #  # ][ #  # ]:          0 :                     css::uno::Reference< css::uno::XInterface >());
                 [ #  # ]
     307                 :            :             }
     308                 :      48213 :             hasName = true;
     309         [ +  - ]:      48213 :             xmlreader::Span s(reader.getAttributeValue(false));
     310         [ +  - ]:      48213 :             buf.append(s.begin, s.length);
     311   [ #  #  #  # ]:          0 :         } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
                 [ #  # ]
     312                 :          0 :                    attrLn.equals(RTL_CONSTASCII_STRINGPARAM("op")))
     313                 :            :         {
     314 [ #  # ][ #  # ]:          0 :             op = parseOperation(reader.getAttributeValue(true));
     315   [ #  #  #  # ]:          0 :         } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
                 [ #  # ]
     316                 :          0 :                    attrLn.equals(RTL_CONSTASCII_STRINGPARAM("finalized")))
     317                 :            :         {
     318 [ #  # ][ #  # ]:          0 :             finalized = xmldata::parseBoolean(reader.getAttributeValue(true));
     319                 :            :         }
     320                 :            :     }
     321         [ -  + ]:      48213 :     if (!hasPackage) {
     322                 :            :         throw css::uno::RuntimeException(
     323                 :            :             (rtl::OUString(
     324                 :            :                 RTL_CONSTASCII_USTRINGPARAM(
     325                 :            :                     "no component-data package attribute in ")) +
     326                 :            :              reader.getUrl()),
     327 [ #  # ][ #  # ]:          0 :             css::uno::Reference< css::uno::XInterface >());
                 [ #  # ]
     328                 :            :     }
     329         [ -  + ]:      48213 :     if (!hasName) {
     330                 :            :         throw css::uno::RuntimeException(
     331                 :            :             (rtl::OUString(
     332                 :            :                 RTL_CONSTASCII_USTRINGPARAM(
     333                 :            :                     "no component-data name attribute in ")) +
     334                 :            :              reader.getUrl()),
     335 [ #  # ][ #  # ]:          0 :             css::uno::Reference< css::uno::XInterface >());
                 [ #  # ]
     336                 :            :     }
     337                 :            :     componentName_ = xmlreader::Span(buf.getStr(), buf.getLength()).
     338         [ +  - ]:      48213 :         convertFromUtf8();
     339         [ -  + ]:      48213 :     if (trackPath_) {
     340                 :            :         assert(path_.empty());
     341         [ #  # ]:          0 :         path_.push_back(componentName_);
     342 [ #  # ][ #  # ]:          0 :         if (partial_ != 0 && partial_->contains(path_) == Partial::CONTAINS_NOT)
         [ #  # ][ #  # ]
     343                 :            :         {
     344 [ #  # ][ #  # ]:          0 :             state_.push(State(true)); // ignored
                 [ #  # ]
     345                 :            :             return;
     346                 :            :         }
     347                 :            :     }
     348                 :            :     rtl::Reference< Node > node(
     349                 :            :         Data::findNode(
     350 [ +  - ][ +  - ]:      48213 :             valueParser_.getLayer(), data_.getComponents(), componentName_));
                 [ +  - ]
     351         [ -  + ]:      48213 :     if (!node.is()) {
     352                 :            :         SAL_WARN(
     353                 :            :             "configmgr",
     354                 :            :             "unknown component \"" << componentName_ << "\" in \""
     355                 :            :                 << reader.getUrl() << '"');
     356 [ #  # ][ #  # ]:          0 :         state_.push(State(true)); // ignored
                 [ #  # ]
     357                 :            :         return;
     358                 :            :     }
     359         [ +  - ]:      48213 :     switch (op) {
     360                 :            :     case OPERATION_MODIFY:
     361                 :            :     case OPERATION_FUSE:
     362                 :      48213 :         break;
     363                 :            :     default:
     364                 :            :         throw css::uno::RuntimeException(
     365                 :            :             (rtl::OUString(
     366                 :            :                 RTL_CONSTASCII_USTRINGPARAM(
     367                 :            :                     "invalid operation on root node in ")) +
     368                 :            :              reader.getUrl()),
     369 [ #  # ][ #  # ]:          0 :             css::uno::Reference< css::uno::XInterface >());
                 [ #  # ]
     370                 :            :     }
     371                 :            :     int finalizedLayer = std::min(
     372                 :          0 :         finalized ? valueParser_.getLayer() : Data::NO_LAYER,
     373 [ +  - ][ -  + ]:      48213 :         node->getFinalized());
         [ #  # ][ +  - ]
     374         [ +  - ]:      48213 :     node->setFinalized(finalizedLayer);
     375 [ +  - ][ +  - ]:      48213 :     state_.push(State(node, finalizedLayer < valueParser_.getLayer()));
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
                 [ +  - ]
     376                 :            : }
     377                 :            : 
     378                 :      12412 : void XcuParser::handleItem(xmlreader::XmlReader & reader) {
     379                 :      12412 :     xmlreader::Span attrPath;
     380                 :      12412 :     for (;;) {
     381                 :            :         int attrNsId;
     382                 :      24824 :         xmlreader::Span attrLn;
     383 [ +  + ][ +  - ]:      24824 :         if (!reader.nextAttribute(&attrNsId, &attrLn)) {
     384                 :            :             break;
     385                 :            :         }
     386   [ +  -  +  - ]:      24824 :         if (attrNsId == ParseManager::NAMESPACE_OOR &&
                 [ +  - ]
     387                 :      12412 :             attrLn.equals(RTL_CONSTASCII_STRINGPARAM("path")))
     388                 :            :         {
     389         [ +  - ]:      12412 :             attrPath = reader.getAttributeValue(false);
     390                 :            :         }
     391                 :            :     }
     392         [ -  + ]:      12412 :     if (!attrPath.is()) {
     393                 :            :         throw css::uno::RuntimeException(
     394                 :            :             (rtl::OUString(
     395                 :            :                 RTL_CONSTASCII_USTRINGPARAM("missing path attribute in ")) +
     396                 :            :              reader.getUrl()),
     397 [ #  # ][ #  # ]:          0 :             css::uno::Reference< css::uno::XInterface >());
                 [ #  # ]
     398                 :            :     }
     399         [ +  - ]:      12412 :     rtl::OUString path(attrPath.convertFromUtf8());
     400                 :            :     int finalizedLayer;
     401                 :            :     rtl::Reference< Node > node(
     402                 :            :         data_.resolvePathRepresentation(
     403         [ +  - ]:      12412 :             path, 0, &path_, &finalizedLayer));
     404         [ -  + ]:      12412 :     if (!node.is()) {
     405                 :            :         SAL_WARN(
     406                 :            :             "configmgr",
     407                 :            :             "unknown item \"" << path << "\" in \"" << reader.getUrl() << '"');
     408 [ #  # ][ #  # ]:          0 :         state_.push(State(true)); // ignored
                 [ #  # ]
     409                 :            :         return;
     410                 :            :     }
     411                 :            :     assert(!path_.empty());
     412         [ +  - ]:      12412 :     componentName_ = path_.front();
     413         [ +  - ]:      12412 :     if (trackPath_) {
     414 [ -  + ][ #  # ]:      12412 :         if (partial_ != 0 && partial_->contains(path_) == Partial::CONTAINS_NOT)
         [ #  # ][ -  + ]
     415                 :            :         {
     416 [ #  # ][ #  # ]:          0 :             state_.push(State(true)); // ignored
                 [ #  # ]
     417                 :            :             return;
     418                 :            :         }
     419                 :            :     } else {
     420                 :          0 :         path_.clear();
     421                 :            :     }
     422         [ +  - ]:      12412 :     switch (node->kind()) {
              [ -  +  + ]
     423                 :            :     case Node::KIND_PROPERTY:
     424                 :            :     case Node::KIND_LOCALIZED_VALUE:
     425                 :            :         SAL_WARN(
     426                 :            :             "configmgr",
     427                 :            :             "item of bad type \"" << path << "\" in \"" << reader.getUrl()
     428                 :            :                 << '"');
     429 [ #  # ][ #  # ]:          0 :         state_.push(State(true)); // ignored
                 [ #  # ]
     430                 :            :         return;
     431                 :            :     case Node::KIND_LOCALIZED_PROPERTY:
     432                 :            :         valueParser_.type_ = dynamic_cast< LocalizedPropertyNode * >(
     433 [ -  + ][ +  - ]:         84 :             node.get())->getStaticType();
     434                 :         84 :         break;
     435                 :            :     default:
     436                 :      12328 :         break;
     437                 :            :     }
     438 [ +  - ][ +  - ]:      12412 :     state_.push(State(node, finalizedLayer < valueParser_.getLayer()));
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
                 [ +  - ]
     439                 :            : }
     440                 :            : 
     441                 :    4342847 : void XcuParser::handlePropValue(
     442                 :            :     xmlreader::XmlReader & reader, PropertyNode * prop)
     443                 :            :  {
     444                 :    4342847 :     bool nil = false;
     445                 :    4342847 :     rtl::OString separator;
     446                 :    4342847 :     rtl::OUString external;
     447                 :      40657 :     for (;;) {
     448                 :            :         int attrNsId;
     449                 :    4383504 :         xmlreader::Span attrLn;
     450 [ +  + ][ +  - ]:    4383504 :         if (!reader.nextAttribute(&attrNsId, &attrLn)) {
     451                 :            :             break;
     452                 :            :         }
     453   [ +  +  +  - ]:      41003 :         if (attrNsId == ParseManager::NAMESPACE_XSI &&
                 [ +  + ]
     454                 :        346 :             attrLn.equals(RTL_CONSTASCII_STRINGPARAM("nil")))
     455                 :            :         {
     456 [ +  - ][ +  - ]:        346 :             nil = xmldata::parseBoolean(reader.getAttributeValue(true));
     457   [ +  +  -  + ]:      71550 :         } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
                 [ -  + ]
     458                 :      31239 :             attrLn.equals(RTL_CONSTASCII_STRINGPARAM("type")))
     459                 :            :         {
     460                 :            :             Type type = xmldata::parseType(
     461 [ #  # ][ #  # ]:          0 :                 reader, reader.getAttributeValue(true));
     462 [ #  # ][ #  # ]:          0 :             if (valueParser_.type_ != TYPE_ANY && type != valueParser_.type_) {
     463                 :            :                 throw css::uno::RuntimeException(
     464                 :            :                     (rtl::OUString(
     465                 :            :                         RTL_CONSTASCII_USTRINGPARAM("invalid value type in ")) +
     466                 :            :                      reader.getUrl()),
     467 [ #  # ][ #  # ]:          0 :                     css::uno::Reference< css::uno::XInterface >());
                 [ #  # ]
     468                 :            :             }
     469                 :          0 :             valueParser_.type_ = type;
     470   [ +  +  +  + ]:      71550 :         } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
                 [ +  + ]
     471                 :      31239 :             attrLn.equals(RTL_CONSTASCII_STRINGPARAM("separator")))
     472                 :            :         {
     473         [ +  - ]:      22794 :             xmlreader::Span s(reader.getAttributeValue(false));
     474         [ -  + ]:      22794 :             if (s.length == 0) {
     475                 :            :                 throw css::uno::RuntimeException(
     476                 :            :                     (rtl::OUString(
     477                 :            :                         RTL_CONSTASCII_USTRINGPARAM(
     478                 :            :                             "bad oor:separator attribute in ")) +
     479                 :            :                      reader.getUrl()),
     480 [ #  # ][ #  # ]:          0 :                     css::uno::Reference< css::uno::XInterface >());
                 [ #  # ]
     481                 :            :             }
     482                 :      22794 :             separator = rtl::OString(s.begin, s.length);
     483   [ +  +  +  - ]:      25962 :         } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
                 [ +  + ]
     484                 :       8445 :             attrLn.equals(RTL_CONSTASCII_STRINGPARAM("external")))
     485                 :            :         {
     486 [ +  - ][ +  - ]:       8445 :             external = reader.getAttributeValue(true).convertFromUtf8();
     487         [ -  + ]:       8445 :             if (external.isEmpty()) {
     488                 :            :                 throw css::uno::RuntimeException(
     489                 :            :                     (rtl::OUString(
     490                 :            :                         RTL_CONSTASCII_USTRINGPARAM(
     491                 :            :                             "bad oor:external attribute value in ")) +
     492                 :            :                      reader.getUrl()),
     493 [ #  # ][ #  # ]:          0 :                     css::uno::Reference< css::uno::XInterface >());
                 [ #  # ]
     494                 :            :             }
     495                 :            :         }
     496                 :            :     }
     497         [ +  + ]:    4342847 :     if (nil) {
     498 [ +  - ][ -  + ]:        346 :         if (!prop->isNillable()) {
     499                 :            :             throw css::uno::RuntimeException(
     500                 :            :                 (rtl::OUString(
     501                 :            :                     RTL_CONSTASCII_USTRINGPARAM(
     502                 :            :                         "xsi:nil attribute for non-nillable prop in ")) +
     503                 :            :                  reader.getUrl()),
     504 [ #  # ][ #  # ]:          0 :                 css::uno::Reference< css::uno::XInterface >());
                 [ #  # ]
     505                 :            :         }
     506         [ -  + ]:        346 :         if (!external.isEmpty()) {
     507                 :            :             throw css::uno::RuntimeException(
     508                 :            :                 (rtl::OUString(
     509                 :            :                     RTL_CONSTASCII_USTRINGPARAM(
     510                 :            :                         "xsi:nil and oor:external attributes for prop in ")) +
     511                 :            :                  reader.getUrl()),
     512 [ #  # ][ #  # ]:          0 :                 css::uno::Reference< css::uno::XInterface >());
                 [ #  # ]
     513                 :            :         }
     514 [ +  - ][ +  - ]:        346 :         prop->setValue(valueParser_.getLayer(), css::uno::Any());
     515 [ +  - ][ +  - ]:        346 :         state_.push(State(false));
                 [ +  - ]
     516         [ +  + ]:    4342501 :     } else if (external.isEmpty()) {
     517                 :    4334056 :         valueParser_.separator_ = separator;
     518 [ +  - ][ +  - ]:    4334056 :         valueParser_.start(prop);
                 [ +  - ]
     519                 :            :     } else {
     520 [ +  - ][ +  - ]:       8445 :         prop->setExternal(valueParser_.getLayer(), external);
     521 [ +  - ][ +  - ]:       8445 :         state_.push(State(false));
                 [ +  - ]
     522                 :    4342847 :     }
     523                 :    4342847 : }
     524                 :            : 
     525                 :    1810940 : void XcuParser::handleLocpropValue(
     526                 :            :     xmlreader::XmlReader & reader, LocalizedPropertyNode * locprop)
     527                 :            : {
     528                 :    1810940 :     rtl::OUString name;
     529                 :    1810940 :     bool nil = false;
     530                 :    1810940 :     rtl::OString separator;
     531                 :    1810940 :     Operation op = OPERATION_FUSE;
     532                 :    1731012 :     for (;;) {
     533                 :            :         int attrNsId;
     534                 :    3541952 :         xmlreader::Span attrLn;
     535 [ +  + ][ +  - ]:    3541952 :         if (!reader.nextAttribute(&attrNsId, &attrLn)) {
     536                 :            :             break;
     537                 :            :         }
     538   [ +  +  +  - ]:    3460803 :         if (attrNsId == xmlreader::XmlReader::NAMESPACE_XML &&
                 [ +  + ]
     539                 :    1729791 :             attrLn.equals(RTL_CONSTASCII_STRINGPARAM("lang")))
     540                 :            :         {
     541 [ +  - ][ +  - ]:    1729791 :             name = reader.getAttributeValue(false).convertFromUtf8();
     542   [ -  +  #  # ]:       1221 :         } else if (attrNsId == ParseManager::NAMESPACE_XSI &&
                 [ -  + ]
     543                 :          0 :             attrLn.equals(RTL_CONSTASCII_STRINGPARAM("nil")))
     544                 :            :         {
     545 [ #  # ][ #  # ]:          0 :             nil = xmldata::parseBoolean(reader.getAttributeValue(true));
     546   [ +  -  -  + ]:       2442 :         } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
                 [ -  + ]
     547                 :       1221 :             attrLn.equals(RTL_CONSTASCII_STRINGPARAM("type")))
     548                 :            :         {
     549                 :            :             Type type = xmldata::parseType(
     550 [ #  # ][ #  # ]:          0 :                 reader, reader.getAttributeValue(true));
     551 [ #  # ][ #  # ]:          0 :             if (valueParser_.type_ != TYPE_ANY && type != valueParser_.type_) {
     552                 :            :                 throw css::uno::RuntimeException(
     553                 :            :                     (rtl::OUString(
     554                 :            :                         RTL_CONSTASCII_USTRINGPARAM("invalid value type in ")) +
     555                 :            :                      reader.getUrl()),
     556 [ #  # ][ #  # ]:          0 :                     css::uno::Reference< css::uno::XInterface >());
                 [ #  # ]
     557                 :            :             }
     558                 :          0 :             valueParser_.type_ = type;
     559   [ +  -  +  - ]:       2442 :         } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
                 [ +  - ]
     560                 :       1221 :             attrLn.equals(RTL_CONSTASCII_STRINGPARAM("separator")))
     561                 :            :         {
     562         [ +  - ]:       1221 :             xmlreader::Span s(reader.getAttributeValue(false));
     563         [ -  + ]:       1221 :             if (s.length == 0) {
     564                 :            :                 throw css::uno::RuntimeException(
     565                 :            :                     (rtl::OUString(
     566                 :            :                         RTL_CONSTASCII_USTRINGPARAM(
     567                 :            :                             "bad oor:separator attribute in ")) +
     568                 :            :                      reader.getUrl()),
     569 [ #  # ][ #  # ]:          0 :                     css::uno::Reference< css::uno::XInterface >());
                 [ #  # ]
     570                 :            :             }
     571                 :       1221 :             separator = rtl::OString(s.begin, s.length);
     572   [ #  #  #  # ]:          0 :         } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
                 [ #  # ]
     573                 :          0 :             attrLn.equals(RTL_CONSTASCII_STRINGPARAM("op")))
     574                 :            :         {
     575 [ #  # ][ #  # ]:          0 :             op = parseOperation(reader.getAttributeValue(true));
     576                 :            :         }
     577                 :            :     }
     578         [ +  + ]:    1810940 :     if (trackPath_) {
     579         [ +  - ]:         84 :         path_.push_back(name);
     580 [ -  + ][ #  # ]:         84 :         if (partial_ != 0 &&
                 [ -  + ]
     581         [ #  # ]:          0 :             partial_->contains(path_) != Partial::CONTAINS_NODE)
     582                 :            :         {
     583 [ #  # ][ #  # ]:          0 :             state_.push(State(true)); // ignored
                 [ #  # ]
     584                 :            :             return;
     585                 :            :         }
     586                 :            :     }
     587         [ +  - ]:    1810940 :     NodeMap & members = locprop->getMembers();
     588         [ +  - ]:    1810940 :     NodeMap::iterator i(members.find(name));
     589 [ +  + ][ +  - ]:    1810940 :     if (i != members.end() && i->second->getLayer() > valueParser_.getLayer()) {
         [ +  - ][ -  + ]
                 [ +  - ]
           [ -  +  #  # ]
     590 [ #  # ][ #  # ]:          0 :         state_.push(State(true)); // ignored
                 [ #  # ]
     591                 :            :         return;
     592                 :            :     }
     593 [ -  + ][ #  # ]:    1810940 :     if (nil && !locprop->isNillable()) {
         [ #  # ][ -  + ]
     594                 :            :         throw css::uno::RuntimeException(
     595                 :            :             (rtl::OUString(
     596                 :            :                 RTL_CONSTASCII_USTRINGPARAM(
     597                 :            :                     "xsi:nil attribute for non-nillable prop in ")) +
     598                 :            :              reader.getUrl()),
     599 [ #  # ][ #  # ]:          0 :             css::uno::Reference< css::uno::XInterface >());
                 [ #  # ]
     600                 :            :     }
     601      [ +  -  - ]:    1810940 :     switch (op) {
     602                 :            :     case OPERATION_FUSE:
     603                 :            :         {
     604                 :    1810940 :             bool pop = false;
     605         [ -  + ]:    1810940 :             if (nil) {
     606         [ #  # ]:          0 :                 if (i == members.end()) {
     607         [ #  # ]:          0 :                     members[name] = new LocalizedValueNode(
     608 [ #  # ][ #  # ]:          0 :                         valueParser_.getLayer(), css::uno::Any());
         [ #  # ][ #  # ]
     609                 :            :                 } else {
     610                 :            :                     dynamic_cast< LocalizedValueNode * >(
     611                 :          0 :                         i->second.get())->setValue(
     612   [ #  #  #  # ]:          0 :                             valueParser_.getLayer(), css::uno::Any());
                 [ #  # ]
     613                 :            :                 }
     614 [ #  # ][ #  # ]:          0 :                 state_.push(State(true));
                 [ #  # ]
     615                 :            :             } else {
     616                 :    1810940 :                 valueParser_.separator_ = separator;
     617 [ +  - ][ +  - ]:    1810940 :                 valueParser_.start(locprop, name);
                 [ +  - ]
     618                 :    1810940 :                 pop = true;
     619                 :            :             }
     620         [ +  + ]:    1810940 :             if (trackPath_) {
     621         [ +  - ]:         84 :                 recordModification(false);
     622         [ +  - ]:         84 :                 if (pop) {
     623         [ +  - ]:         84 :                     path_.pop_back();
     624                 :            :                 }
     625                 :            :             }
     626                 :            :         }
     627                 :    1810940 :         break;
     628                 :            :     case OPERATION_REMOVE:
     629                 :            :         //TODO: only allow if parent.op == OPERATION_FUSE
     630                 :            :         //TODO: disallow removing when e.g. lang=""?
     631         [ #  # ]:          0 :         if (i != members.end()) {
     632         [ #  # ]:          0 :             members.erase(i);
     633                 :            :         }
     634 [ #  # ][ #  # ]:          0 :         state_.push(State(true));
                 [ #  # ]
     635         [ #  # ]:          0 :         recordModification(false);
     636                 :          0 :         break;
     637                 :            :     default:
     638                 :            :         throw css::uno::RuntimeException(
     639                 :            :             (rtl::OUString(
     640                 :            :                 RTL_CONSTASCII_USTRINGPARAM(
     641                 :            :                     "bad op attribute for value element in ")) +
     642                 :            :              reader.getUrl()),
     643 [ #  # ][ #  # ]:    1810940 :             css::uno::Reference< css::uno::XInterface >());
                 [ #  # ]
     644 [ -  + ][ +  - ]:    1810940 :     }
     645                 :            : }
     646                 :            : 
     647                 :    6426494 : void XcuParser::handleGroupProp(
     648                 :            :     xmlreader::XmlReader & reader, GroupNode * group)
     649                 :            : {
     650                 :    6426494 :     bool hasName = false;
     651                 :    6426494 :     rtl::OUString name;
     652                 :    6426494 :     Type type = TYPE_ERROR;
     653                 :    6426494 :     Operation op = OPERATION_MODIFY;
     654                 :    6426494 :     bool finalized = false;
     655                 :    8459570 :     for (;;) {
     656                 :            :         int attrNsId;
     657                 :   14886064 :         xmlreader::Span attrLn;
     658 [ +  + ][ +  - ]:   14886064 :         if (!reader.nextAttribute(&attrNsId, &attrLn)) {
     659                 :            :             break;
     660                 :            :         }
     661   [ +  -  +  + ]:   16919140 :         if (attrNsId == ParseManager::NAMESPACE_OOR &&
                 [ +  + ]
     662                 :    8459570 :                    attrLn.equals(RTL_CONSTASCII_STRINGPARAM("name")))
     663                 :            :         {
     664                 :    6426494 :             hasName = true;
     665 [ +  - ][ +  - ]:    6426494 :             name = reader.getAttributeValue(false).convertFromUtf8();
     666   [ +  -  +  + ]:    4066152 :         } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
                 [ +  + ]
     667                 :    2033076 :                    attrLn.equals(RTL_CONSTASCII_STRINGPARAM("type")))
     668                 :            :         {
     669 [ +  - ][ +  - ]:    1907463 :             type = xmldata::parseType(reader, reader.getAttributeValue(true));
     670   [ +  -  +  + ]:     251226 :         } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
                 [ +  + ]
     671                 :     125613 :                    attrLn.equals(RTL_CONSTASCII_STRINGPARAM("op")))
     672                 :            :         {
     673 [ +  - ][ +  - ]:      97866 :             op = parseOperation(reader.getAttributeValue(true));
     674   [ +  -  +  - ]:      55494 :         } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
                 [ +  - ]
     675                 :      27747 :                    attrLn.equals(RTL_CONSTASCII_STRINGPARAM("finalized")))
     676                 :            :         {
     677 [ +  - ][ +  - ]:      27747 :             finalized = xmldata::parseBoolean(reader.getAttributeValue(true));
     678                 :            :         }
     679                 :            :     }
     680         [ -  + ]:    6426494 :     if (!hasName) {
     681                 :            :         throw css::uno::RuntimeException(
     682                 :            :             (rtl::OUString(
     683                 :            :                 RTL_CONSTASCII_USTRINGPARAM("no prop name attribute in ")) +
     684                 :            :              reader.getUrl()),
     685 [ #  # ][ #  # ]:          0 :             css::uno::Reference< css::uno::XInterface >());
                 [ #  # ]
     686                 :            :     }
     687         [ +  + ]:    6426494 :     if (trackPath_) {
     688         [ +  - ]:      13980 :         path_.push_back(name);
     689                 :            :         //TODO: This ignores locprop values for which specific include paths
     690                 :            :         // exist (i.e., for which contains(locprop path) = CONTAINS_SUBNODES):
     691 [ -  + ][ #  # ]:      13980 :         if (partial_ != 0 &&
                 [ -  + ]
     692         [ #  # ]:          0 :             partial_->contains(path_) != Partial::CONTAINS_NODE)
     693                 :            :         {
     694 [ #  # ][ #  # ]:          0 :             state_.push(State(true)); // ignored
                 [ #  # ]
     695                 :    6426494 :             return;
     696                 :            :         }
     697                 :            :     }
     698         [ +  - ]:    6426494 :     NodeMap & members = group->getMembers();
     699         [ +  - ]:    6426494 :     NodeMap::iterator i(members.find(name));
     700         [ +  + ]:    6426494 :     if (i == members.end()) {
     701         [ +  - ]:      92440 :         handleUnknownGroupProp(reader, group, name, type, op, finalized);
     702                 :            :     } else {
     703         [ +  - ]:    6334054 :         switch (i->second->kind()) {
              [ +  +  - ]
     704                 :            :         case Node::KIND_PROPERTY:
     705         [ +  - ]:    4494582 :             handlePlainGroupProp(reader, group, i, name, type, op, finalized);
     706                 :    4494582 :             break;
     707                 :            :         case Node::KIND_LOCALIZED_PROPERTY:
     708                 :            :             handleLocalizedGroupProp(
     709                 :            :                 reader,
     710                 :    1839472 :                 dynamic_cast< LocalizedPropertyNode * >(i->second.get()), name,
     711 [ +  - ][ -  + ]:    1839472 :                 type, op, finalized);
     712                 :    1839472 :             break;
     713                 :            :         default:
     714                 :            :             throw css::uno::RuntimeException(
     715                 :            :                 (rtl::OUString(
     716                 :            :                     RTL_CONSTASCII_USTRINGPARAM("inappropriate prop ")) +
     717                 :            :                  name + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) +
     718                 :            :                  reader.getUrl()),
     719 [ #  # ][ #  # ]:    6426494 :                 css::uno::Reference< css::uno::XInterface >());
         [ #  # ][ #  # ]
     720                 :            :         }
     721         [ +  - ]:    6426494 :     }
     722                 :            : }
     723                 :            : 
     724                 :      92440 : void XcuParser::handleUnknownGroupProp(
     725                 :            :     xmlreader::XmlReader const & reader, GroupNode * group,
     726                 :            :     rtl::OUString const & name, Type type, Operation operation, bool finalized)
     727                 :            : {
     728         [ +  - ]:      92440 :     switch (operation) {
     729                 :            :     case OPERATION_REPLACE:
     730                 :            :     case OPERATION_FUSE:
     731         [ +  - ]:      92440 :         if (group->isExtensible()) {
     732         [ -  + ]:      92440 :             if (type == TYPE_ERROR) {
     733                 :            :                 throw css::uno::RuntimeException(
     734                 :            :                     (rtl::OUString(
     735                 :            :                         RTL_CONSTASCII_USTRINGPARAM(
     736                 :            :                             "missing type attribute for prop ")) +
     737                 :            :                  name + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) +
     738                 :            :                  reader.getUrl()),
     739 [ #  # ][ #  # ]:          0 :                 css::uno::Reference< css::uno::XInterface >());
         [ #  # ][ #  # ]
     740                 :            :             }
     741                 :      92440 :             valueParser_.type_ = type;
     742                 :            :             rtl::Reference< Node > prop(
     743                 :            :                 new PropertyNode(
     744                 :      92440 :                     valueParser_.getLayer(), TYPE_ANY, true, css::uno::Any(),
     745 [ +  - ][ +  - ]:      92440 :                     true));
         [ +  - ][ +  - ]
     746         [ -  + ]:      92440 :             if (finalized) {
     747 [ #  # ][ #  # ]:          0 :                 prop->setFinalized(valueParser_.getLayer());
     748                 :            :             }
     749 [ +  - ][ +  - ]:      92440 :             state_.push(State(prop, name, state_.top().locked));
         [ +  - ][ +  - ]
     750         [ +  - ]:      92440 :             recordModification(false);
     751         [ +  - ]:      92440 :             break;
     752                 :            :         }
     753                 :            :         // fall through
     754                 :            :     default:
     755                 :            :         SAL_WARN(
     756                 :            :             "configmgr",
     757                 :            :             "unknown property \"" << name << "\" in \"" << reader.getUrl()
     758                 :            :                 << '"');
     759         [ #  # ]:          0 :         state_.push(State(true)); // ignored
     760                 :          0 :         break;
     761                 :            :     }
     762                 :      92440 : }
     763                 :            : 
     764                 :    4494582 : void XcuParser::handlePlainGroupProp(
     765                 :            :     xmlreader::XmlReader const & reader, GroupNode * group,
     766                 :            :     NodeMap::iterator const & propertyIndex, rtl::OUString const & name,
     767                 :            :     Type type, Operation operation, bool finalized)
     768                 :            : {
     769                 :            :     PropertyNode * property = dynamic_cast< PropertyNode * >(
     770         [ -  + ]:    4494582 :         propertyIndex->second.get());
     771         [ -  + ]:    4494582 :     if (property->getLayer() > valueParser_.getLayer()) {
     772         [ #  # ]:          0 :         state_.push(State(true)); // ignored
     773                 :    4494582 :         return;
     774                 :            :     }
     775                 :            :     int finalizedLayer = std::min(
     776                 :      27747 :         finalized ? valueParser_.getLayer() : Data::NO_LAYER,
     777 [ +  + ][ +  - ]:    4494582 :         property->getFinalized());
                 [ +  - ]
     778                 :    4494582 :     property->setFinalized(finalizedLayer);
     779   [ +  +  -  + ]:    5366806 :     if (type != TYPE_ERROR && property->getStaticType() != TYPE_ANY &&
         [ -  + ][ +  + ]
     780                 :     872224 :         type != property->getStaticType())
     781                 :            :     {
     782                 :            :         throw css::uno::RuntimeException(
     783                 :            :             (rtl::OUString(
     784                 :            :                 RTL_CONSTASCII_USTRINGPARAM("invalid type for prop ")) +
     785                 :            :              name + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) +
     786                 :            :              reader.getUrl()),
     787 [ #  # ][ #  # ]:          0 :             css::uno::Reference< css::uno::XInterface >());
         [ #  # ][ #  # ]
     788                 :            :     }
     789         [ +  + ]:    4494582 :     valueParser_.type_ = type == TYPE_ERROR ? property->getStaticType() : type;
     790      [ +  -  - ]:    4494582 :     switch (operation) {
     791                 :            :     case OPERATION_MODIFY:
     792                 :            :     case OPERATION_REPLACE:
     793                 :            :     case OPERATION_FUSE:
     794                 :            :         state_.push(
     795                 :            :             State(
     796                 :            :                 property,
     797                 :    4494582 :                 (state_.top().locked ||
     798 [ -  + ][ +  - ]:    4494582 :                  finalizedLayer < valueParser_.getLayer())));
         [ +  - ][ +  - ]
                 [ +  - ]
     799                 :    4494582 :         recordModification(false);
     800                 :    4494582 :         break;
     801                 :            :     case OPERATION_REMOVE:
     802         [ #  # ]:          0 :         if (!property->isExtension()) {
     803                 :            :             throw css::uno::RuntimeException(
     804                 :            :                 (rtl::OUString(
     805                 :            :                     RTL_CONSTASCII_USTRINGPARAM(
     806                 :            :                         "invalid remove of non-extension prop ")) +
     807                 :            :                  name + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) +
     808                 :            :                  reader.getUrl()),
     809 [ #  # ][ #  # ]:          0 :                 css::uno::Reference< css::uno::XInterface >());
         [ #  # ][ #  # ]
     810                 :            :         }
     811                 :          0 :         group->getMembers().erase(propertyIndex);
     812         [ #  # ]:          0 :         state_.push(State(true)); // ignore children
     813                 :          0 :         recordModification(false);
     814                 :          0 :         break;
     815                 :            :     }
     816                 :            : }
     817                 :            : 
     818                 :    1839472 : void XcuParser::handleLocalizedGroupProp(
     819                 :            :     xmlreader::XmlReader const & reader, LocalizedPropertyNode * property,
     820                 :            :     rtl::OUString const & name, Type type, Operation operation, bool finalized)
     821                 :            : {
     822         [ -  + ]:    1839472 :     if (property->getLayer() > valueParser_.getLayer()) {
     823         [ #  # ]:          0 :         state_.push(State(true)); // ignored
     824                 :    1839472 :         return;
     825                 :            :     }
     826                 :            :     int finalizedLayer = std::min(
     827                 :          0 :         finalized ? valueParser_.getLayer() : Data::NO_LAYER,
     828 [ -  + ][ #  # ]:    1839472 :         property->getFinalized());
                 [ +  - ]
     829                 :    1839472 :     property->setFinalized(finalizedLayer);
     830   [ +  +  -  + ]:    2763813 :     if (type != TYPE_ERROR && property->getStaticType() != TYPE_ANY &&
         [ -  + ][ +  + ]
     831                 :     924341 :         type != property->getStaticType())
     832                 :            :     {
     833                 :            :         throw css::uno::RuntimeException(
     834                 :            :             (rtl::OUString(
     835                 :            :                 RTL_CONSTASCII_USTRINGPARAM("invalid type for prop ")) +
     836                 :            :              name + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) +
     837                 :            :              reader.getUrl()),
     838 [ #  # ][ #  # ]:          0 :             css::uno::Reference< css::uno::XInterface >());
         [ #  # ][ #  # ]
     839                 :            :     }
     840         [ +  + ]:    1839472 :     valueParser_.type_ = type == TYPE_ERROR ? property->getStaticType() : type;
     841   [ +  -  -  - ]:    1839472 :     switch (operation) {
     842                 :            :     case OPERATION_MODIFY:
     843                 :            :     case OPERATION_FUSE:
     844                 :            :         state_.push(
     845                 :            :             State(
     846                 :            :                 property,
     847                 :    1839472 :                 (state_.top().locked ||
     848 [ -  + ][ +  - ]:    1839472 :                  finalizedLayer < valueParser_.getLayer())));
         [ +  - ][ +  - ]
                 [ +  - ]
     849                 :    1839472 :         break;
     850                 :            :     case OPERATION_REPLACE:
     851                 :            :         {
     852                 :            :             rtl::Reference< Node > replacement(
     853                 :            :                 new LocalizedPropertyNode(
     854                 :          0 :                     valueParser_.getLayer(), property->getStaticType(),
     855 [ #  # ][ #  # ]:          0 :                     property->isNillable()));
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     856 [ #  # ][ #  # ]:          0 :             replacement->setFinalized(property->getFinalized());
     857                 :            :             state_.push(
     858                 :            :                 State(
     859                 :            :                     replacement, name,
     860         [ #  # ]:          0 :                     (state_.top().locked ||
     861 [ #  # ][ #  # ]:          0 :                      finalizedLayer < valueParser_.getLayer())));
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     862 [ #  # ][ #  # ]:          0 :             recordModification(false);
     863                 :            :         }
     864                 :          0 :         break;
     865                 :            :     case OPERATION_REMOVE:
     866                 :            :         throw css::uno::RuntimeException(
     867                 :            :             (rtl::OUString(
     868                 :            :                 RTL_CONSTASCII_USTRINGPARAM(
     869                 :            :                     "invalid remove of non-extension prop ")) +
     870                 :            :              name + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) +
     871                 :            :              reader.getUrl()),
     872 [ #  # ][ #  # ]:          0 :             css::uno::Reference< css::uno::XInterface >());
         [ #  # ][ #  # ]
     873                 :            :     }
     874                 :            : }
     875                 :            : 
     876                 :     179623 : void XcuParser::handleGroupNode(
     877                 :            :     xmlreader::XmlReader & reader, rtl::Reference< Node > const & group)
     878                 :            : {
     879                 :     179623 :     bool hasName = false;
     880                 :     179623 :     rtl::OUString name;
     881                 :     179623 :     Operation op = OPERATION_MODIFY;
     882                 :     179623 :     bool finalized = false;
     883                 :     181341 :     for (;;) {
     884                 :            :         int attrNsId;
     885                 :     360964 :         xmlreader::Span attrLn;
     886 [ +  + ][ +  - ]:     360964 :         if (!reader.nextAttribute(&attrNsId, &attrLn)) {
     887                 :            :             break;
     888                 :            :         }
     889   [ +  -  +  + ]:     362682 :         if (attrNsId == ParseManager::NAMESPACE_OOR &&
                 [ +  + ]
     890                 :     181341 :                    attrLn.equals(RTL_CONSTASCII_STRINGPARAM("name")))
     891                 :            :         {
     892                 :     179623 :             hasName = true;
     893 [ +  - ][ +  - ]:     179623 :             name = reader.getAttributeValue(false).convertFromUtf8();
     894   [ +  -  -  + ]:       3436 :         } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
                 [ -  + ]
     895                 :       1718 :                    attrLn.equals(RTL_CONSTASCII_STRINGPARAM("op")))
     896                 :            :         {
     897 [ #  # ][ #  # ]:          0 :             op = parseOperation(reader.getAttributeValue(true));
     898   [ +  -  +  + ]:       3436 :         } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
                 [ +  + ]
     899                 :       1718 :                    attrLn.equals(RTL_CONSTASCII_STRINGPARAM("finalized")))
     900                 :            :         {
     901 [ +  - ][ +  - ]:       1620 :             finalized = xmldata::parseBoolean(reader.getAttributeValue(true));
     902                 :            :         }
     903                 :            :     }
     904         [ -  + ]:     179623 :     if (!hasName) {
     905                 :            :         throw css::uno::RuntimeException(
     906                 :            :             (rtl::OUString(
     907                 :            :                 RTL_CONSTASCII_USTRINGPARAM("no node name attribute in ")) +
     908                 :            :              reader.getUrl()),
     909 [ #  # ][ #  # ]:          0 :             css::uno::Reference< css::uno::XInterface >());
                 [ #  # ]
     910                 :            :     }
     911         [ +  + ]:     179623 :     if (trackPath_) {
     912         [ +  - ]:        510 :         path_.push_back(name);
     913 [ -  + ][ #  # ]:        510 :         if (partial_ != 0 && partial_->contains(path_) == Partial::CONTAINS_NOT)
         [ #  # ][ -  + ]
     914                 :            :         {
     915 [ #  # ][ #  # ]:          0 :             state_.push(State(true)); // ignored
                 [ #  # ]
     916                 :            :             return;
     917                 :            :         }
     918                 :            :     }
     919                 :            :     rtl::Reference< Node > child(
     920 [ +  - ][ +  - ]:     179623 :         Data::findNode(valueParser_.getLayer(), group->getMembers(), name));
                 [ +  - ]
     921         [ -  + ]:     179623 :     if (!child.is()) {
     922                 :            :         SAL_WARN(
     923                 :            :             "configmgr",
     924                 :            :             "unknown node \"" << name << "\" in \"" << reader.getUrl() << '"');
     925 [ #  # ][ #  # ]:          0 :         state_.push(State(true)); // ignored
                 [ #  # ]
     926                 :            :         return;
     927                 :            :     }
     928         [ +  - ]:     179623 :     Node::Kind kind = child->kind();
     929 [ +  + ][ -  + ]:     179623 :     if (kind != Node::KIND_GROUP && kind != Node::KIND_SET) {
     930                 :            :         throw css::uno::RuntimeException(
     931                 :            :             (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("bad <node> \"")) +
     932                 :            :              name +
     933                 :            :              rtl::OUString(
     934                 :            :                  RTL_CONSTASCII_USTRINGPARAM("\" of non group/set kind in ")) +
     935                 :            :              reader.getUrl()),
     936 [ #  # ][ #  # ]:          0 :             css::uno::Reference< css::uno::XInterface >());
         [ #  # ][ #  # ]
     937                 :            :     }
     938 [ -  + ][ #  # ]:     179623 :     if (op != OPERATION_MODIFY && op != OPERATION_FUSE) {
     939                 :            :         throw css::uno::RuntimeException(
     940                 :            :             (rtl::OUString(
     941                 :            :                 RTL_CONSTASCII_USTRINGPARAM(
     942                 :            :                     "invalid operation on group node in ")) +
     943                 :            :              reader.getUrl()),
     944 [ #  # ][ #  # ]:          0 :             css::uno::Reference< css::uno::XInterface >());
                 [ #  # ]
     945                 :            :     }
     946                 :            :     int finalizedLayer = std::min(
     947                 :       1620 :         finalized ? valueParser_.getLayer() : Data::NO_LAYER,
     948 [ +  - ][ +  + ]:     179623 :         child->getFinalized());
         [ +  - ][ +  - ]
     949         [ +  - ]:     179623 :     child->setFinalized(finalizedLayer);
     950                 :            :     state_.push(
     951                 :            :         State(
     952                 :            :             child,
     953 [ +  - ][ +  - ]:     179623 :             state_.top().locked || finalizedLayer < valueParser_.getLayer()));
         [ +  - ][ -  + ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ -  + ][ +  - ]
     954                 :            : }
     955                 :            : 
     956                 :    2517837 : void XcuParser::handleSetNode(xmlreader::XmlReader & reader, SetNode * set) {
     957                 :    2517837 :     bool hasName = false;
     958                 :    2517837 :     rtl::OUString name;
     959                 :    2517837 :     rtl::OUString component(componentName_);
     960                 :    2517837 :     bool hasNodeType = false;
     961                 :    2517837 :     rtl::OUString nodeType;
     962                 :    2517837 :     Operation op = OPERATION_MODIFY;
     963                 :    2517837 :     bool finalized = false;
     964                 :    2517837 :     bool mandatory = false;
     965                 :    5583916 :     for (;;) {
     966                 :            :         int attrNsId;
     967                 :    8101753 :         xmlreader::Span attrLn;
     968 [ +  + ][ +  - ]:    8101753 :         if (!reader.nextAttribute(&attrNsId, &attrLn)) {
     969                 :            :             break;
     970                 :            :         }
     971   [ +  -  +  + ]:   11167832 :         if (attrNsId == ParseManager::NAMESPACE_OOR &&
                 [ +  + ]
     972                 :    5583916 :                    attrLn.equals(RTL_CONSTASCII_STRINGPARAM("name")))
     973                 :            :         {
     974                 :    2517837 :             hasName = true;
     975 [ +  - ][ +  - ]:    2517837 :             name = reader.getAttributeValue(false).convertFromUtf8();
     976   [ +  -  -  + ]:    6132158 :         } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
                 [ -  + ]
     977                 :    3066079 :                    attrLn.equals(RTL_CONSTASCII_STRINGPARAM("component")))
     978                 :            :         {
     979 [ #  # ][ #  # ]:          0 :             component = reader.getAttributeValue(false).convertFromUtf8();
     980   [ +  -  -  + ]:    6132158 :         } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
                 [ -  + ]
     981                 :    3066079 :                    attrLn.equals(RTL_CONSTASCII_STRINGPARAM("node-type")))
     982                 :            :         {
     983                 :          0 :             hasNodeType = true;
     984 [ #  # ][ #  # ]:          0 :             nodeType = reader.getAttributeValue(false).convertFromUtf8();
     985   [ +  -  +  + ]:    6132158 :         } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
                 [ +  + ]
     986                 :    3066079 :                    attrLn.equals(RTL_CONSTASCII_STRINGPARAM("op")))
     987                 :            :         {
     988 [ +  - ][ +  - ]:    2494753 :             op = parseOperation(reader.getAttributeValue(true));
     989   [ +  -  +  + ]:    1142652 :         } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
                 [ +  + ]
     990                 :     571326 :                    attrLn.equals(RTL_CONSTASCII_STRINGPARAM("finalized")))
     991                 :            :         {
     992 [ +  - ][ +  - ]:     560416 :             finalized = xmldata::parseBoolean(reader.getAttributeValue(true));
     993   [ +  -  +  + ]:      21820 :         } else if (attrNsId == ParseManager::NAMESPACE_OOR &&
                 [ +  + ]
     994                 :      10910 :                    attrLn.equals(RTL_CONSTASCII_STRINGPARAM("mandatory")))
     995                 :            :         {
     996 [ +  - ][ +  - ]:      10616 :             mandatory = xmldata::parseBoolean(reader.getAttributeValue(true));
     997                 :            :         }
     998                 :            :     }
     999         [ -  + ]:    2517837 :     if (!hasName) {
    1000                 :            :         throw css::uno::RuntimeException(
    1001                 :            :             (rtl::OUString(
    1002                 :            :                 RTL_CONSTASCII_USTRINGPARAM("no node name attribute in ")) +
    1003                 :            :              reader.getUrl()),
    1004 [ #  # ][ #  # ]:          0 :             css::uno::Reference< css::uno::XInterface >());
                 [ #  # ]
    1005                 :            :     }
    1006         [ +  + ]:    2517837 :     if (trackPath_) {
    1007         [ +  - ]:        902 :         path_.push_back(name);
    1008 [ -  + ][ #  # ]:        902 :         if (partial_ != 0 && partial_->contains(path_) == Partial::CONTAINS_NOT)
         [ #  # ][ -  + ]
    1009                 :            :         {
    1010 [ #  # ][ #  # ]:          0 :             state_.push(State(true)); // ignored
                 [ #  # ]
    1011                 :            :             return;
    1012                 :            :         }
    1013                 :            :     }
    1014                 :            :     rtl::OUString templateName(
    1015                 :            :         xmldata::parseTemplateReference(
    1016 [ +  - ][ +  - ]:    2517837 :             component, hasNodeType, nodeType, &set->getDefaultTemplateName()));
    1017 [ +  - ][ -  + ]:    2517837 :     if (!set->isValidTemplate(templateName)) {
    1018                 :            :         throw css::uno::RuntimeException(
    1019                 :            :             (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("set member node ")) +
    1020                 :            :              name +
    1021                 :            :              rtl::OUString(
    1022                 :            :                  RTL_CONSTASCII_USTRINGPARAM(" references invalid template ")) +
    1023                 :            :              templateName + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) +
    1024                 :            :              reader.getUrl()),
    1025 [ #  # ][ #  # ]:          0 :             css::uno::Reference< css::uno::XInterface >());
         [ #  # ][ #  # ]
                 [ #  # ]
    1026                 :            :     }
    1027                 :            :     rtl::Reference< Node > tmpl(
    1028 [ +  - ][ +  - ]:    2517837 :         data_.getTemplate(valueParser_.getLayer(), templateName));
    1029         [ -  + ]:    2517837 :     if (!tmpl.is()) {
    1030                 :            :         throw css::uno::RuntimeException(
    1031                 :            :             (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("set member node ")) +
    1032                 :            :              name +
    1033                 :            :              rtl::OUString(
    1034                 :            :                  RTL_CONSTASCII_USTRINGPARAM(
    1035                 :            :                      " references undefined template ")) +
    1036                 :            :              templateName + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" in ")) +
    1037                 :            :              reader.getUrl()),
    1038 [ #  # ][ #  # ]:          0 :             css::uno::Reference< css::uno::XInterface >());
         [ #  # ][ #  # ]
                 [ #  # ]
    1039                 :            :     }
    1040 [ +  + ][ +  - ]:    2517837 :     int finalizedLayer = finalized ? valueParser_.getLayer() : Data::NO_LAYER;
    1041 [ +  + ][ +  - ]:    2517837 :     int mandatoryLayer = mandatory ? valueParser_.getLayer() : Data::NO_LAYER;
    1042         [ +  - ]:    2517837 :     NodeMap & members = set->getMembers();
    1043         [ +  - ]:    2517837 :     NodeMap::iterator i(members.find(name));
    1044         [ +  + ]:    2517837 :     if (i != members.end()) {
    1045 [ +  - ][ +  - ]:      40135 :         finalizedLayer = std::min(finalizedLayer, i->second->getFinalized());
    1046         [ +  - ]:      40135 :         i->second->setFinalized(finalizedLayer);
    1047 [ +  - ][ +  - ]:      40135 :         mandatoryLayer = std::min(mandatoryLayer, i->second->getMandatory());
    1048         [ +  - ]:      40135 :         i->second->setMandatory(mandatoryLayer);
    1049 [ +  - ][ +  - ]:      40135 :         if (i->second->getLayer() > valueParser_.getLayer()) {
                 [ -  + ]
    1050 [ #  # ][ #  # ]:          0 :             state_.push(State(true)); // ignored
                 [ #  # ]
    1051                 :            :             return;
    1052                 :            :         }
    1053                 :            :     }
    1054   [ +  +  +  -  :    2517837 :     switch (op) {
                      - ]
    1055                 :            :     case OPERATION_MODIFY:
    1056         [ -  + ]:      23084 :         if (i == members.end()) {
    1057                 :            :             SAL_WARN(
    1058                 :            :                 "configmgr",
    1059                 :            :                 "ignoring modify of unknown set member node \"" << name
    1060                 :            :                     << "\" in \"" << reader.getUrl() << '"');
    1061 [ #  # ][ #  # ]:          0 :             state_.push(State(true)); // ignored
                 [ #  # ]
    1062                 :            :         } else {
    1063                 :            :             state_.push(
    1064                 :            :                 State(
    1065                 :      23084 :                     i->second,
    1066         [ +  - ]:      23084 :                     (state_.top().locked ||
    1067 [ +  - ][ +  - ]:      46168 :                      finalizedLayer < valueParser_.getLayer())));
         [ -  + ][ +  - ]
         [ +  - ][ +  - ]
    1068                 :            :         }
    1069                 :      23084 :         break;
    1070                 :            :     case OPERATION_REPLACE:
    1071 [ +  - ][ +  - ]:    2477477 :         if (state_.top().locked || finalizedLayer < valueParser_.getLayer()) {
         [ +  - ][ -  + ]
                 [ -  + ]
    1072 [ #  # ][ #  # ]:          0 :             state_.push(State(true)); // ignored
                 [ #  # ]
    1073                 :            :         } else {
    1074         [ +  - ]:    2477477 :             rtl::Reference< Node > member(tmpl->clone(true));
    1075 [ +  - ][ +  - ]:    2477477 :             member->setLayer(valueParser_.getLayer());
    1076         [ +  - ]:    2477477 :             member->setFinalized(finalizedLayer);
    1077         [ +  - ]:    2477477 :             member->setMandatory(mandatoryLayer);
    1078 [ +  - ][ +  - ]:    2477477 :             state_.push(State(member, name, false));
                 [ +  - ]
    1079 [ +  - ][ +  - ]:    2477477 :             recordModification(i == members.end());
    1080                 :            :         }
    1081                 :    2477477 :         break;
    1082                 :            :     case OPERATION_FUSE:
    1083         [ +  + ]:      17276 :         if (i == members.end()) {
    1084 [ +  - ][ +  - ]:      17178 :             if (state_.top().locked || finalizedLayer < valueParser_.getLayer())
         [ +  - ][ -  + ]
                 [ -  + ]
    1085                 :            :             {
    1086 [ #  # ][ #  # ]:          0 :                 state_.push(State(true)); // ignored
                 [ #  # ]
    1087                 :            :             } else {
    1088         [ +  - ]:      17178 :                 rtl::Reference< Node > member(tmpl->clone(true));
    1089 [ +  - ][ +  - ]:      17178 :                 member->setLayer(valueParser_.getLayer());
    1090         [ +  - ]:      17178 :                 member->setFinalized(finalizedLayer);
    1091         [ +  - ]:      17178 :                 member->setMandatory(mandatoryLayer);
    1092 [ +  - ][ +  - ]:      17178 :                 state_.push(State(member, name, false));
                 [ +  - ]
    1093 [ +  - ][ +  - ]:      17178 :                 recordModification(true);
    1094                 :            :             }
    1095                 :            :         } else {
    1096                 :            :             state_.push(
    1097                 :            :                 State(
    1098                 :         98 :                     i->second,
    1099         [ +  - ]:         98 :                     (state_.top().locked ||
    1100 [ +  - ][ +  - ]:        196 :                      finalizedLayer < valueParser_.getLayer())));
         [ -  + ][ +  - ]
         [ +  - ][ +  - ]
    1101                 :            :         }
    1102                 :      17276 :         break;
    1103                 :            :     case OPERATION_REMOVE:
    1104                 :            :         {
    1105                 :            :             // Ignore removal of unknown members, members finalized in a lower
    1106                 :            :             // layer, and members made mandatory in this or a lower layer;
    1107                 :            :             // forget about user-layer removals that no longer remove anything
    1108                 :            :             // (so that paired additions/removals in the user layer do not grow
    1109                 :            :             // registrymodifications.xcu unbounded):
    1110                 :          0 :             bool known = i != members.end();
    1111 [ #  # ][ #  # ]:          0 :             if (known && !state_.top().locked &&
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1112         [ #  # ]:          0 :                 finalizedLayer >= valueParser_.getLayer() &&
    1113                 :            :                 (mandatoryLayer == Data::NO_LAYER ||
    1114         [ #  # ]:          0 :                  mandatoryLayer > valueParser_.getLayer()))
    1115                 :            :             {
    1116         [ #  # ]:          0 :                 members.erase(i);
    1117                 :            :             }
    1118 [ #  # ][ #  # ]:          0 :             state_.push(State(true));
                 [ #  # ]
    1119         [ #  # ]:          0 :             if (known) {
    1120         [ #  # ]:          0 :                 recordModification(false);
    1121                 :            :             }
    1122                 :    2517837 :             break;
    1123                 :            :         }
    1124 [ +  - ][ -  + ]:    2517837 :     }
         [ -  + ][ -  + ]
         [ -  + ][ +  - ]
    1125                 :            : }
    1126                 :            : 
    1127                 :    7081761 : void XcuParser::recordModification(bool addition) {
    1128         [ -  + ]:    7081761 :     if (broadcastModifications_ != 0) {
    1129                 :          0 :         broadcastModifications_->add(path_);
    1130                 :            :     }
    1131 [ +  + ][ -  + ]:    7081761 :     if (addition && additions_ != 0) {
    1132                 :          0 :         additions_->push_back(path_);
    1133                 :            :     }
    1134         [ +  + ]:    7081761 :     if (recordModifications_) {
    1135                 :      14966 :         data_.modifications.add(path_);
    1136                 :            :     }
    1137                 :    7081761 : }
    1138                 :            : 
    1139                 :            : }
    1140                 :            : 
    1141                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10