LCOV - code coverage report
Current view: top level - registry/tools - regcompare.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 0 911 0.0 %
Date: 2014-04-11 Functions: 0 36 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * 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             : 
      21             : #include "registry/registry.hxx"
      22             : #include "registry/reader.hxx"
      23             : #include "registry/version.h"
      24             : #include "fileurl.hxx"
      25             : #include "options.hxx"
      26             : 
      27             : #include <rtl/ustring.hxx>
      28             : #include <osl/diagnose.h>
      29             : 
      30             : #include <stdio.h>
      31             : #include <string.h>
      32             : 
      33             : #include <set>
      34             : #include <vector>
      35             : #include <string>
      36             : 
      37             : using namespace rtl;
      38             : using namespace registry::tools;
      39             : 
      40             : typedef std::set< OUString > StringSet;
      41             : 
      42           0 : class Options_Impl : public Options
      43             : {
      44             : public:
      45           0 :     explicit Options_Impl(char const * program)
      46             :         : Options(program),
      47             :           m_bFullCheck(false),
      48             :           m_bForceOutput(false),
      49             :           m_bUnoTypeCheck(false),
      50           0 :           m_checkUnpublished(false)
      51           0 :         {}
      52             : 
      53           0 :     std::string const & getRegName1() const { return m_regName1; }
      54           0 :     std::string const & getRegName2() const { return m_regName2; }
      55             : 
      56           0 :     bool isStartKeyValid() const { return (!m_startKey.isEmpty()); }
      57           0 :     OUString const & getStartKey() const { return m_startKey; }
      58             :     bool matchedWithExcludeKey( const OUString& keyName) const;
      59             : 
      60           0 :     bool fullCheck() const { return m_bFullCheck; }
      61           0 :     bool forceOutput() const { return m_bForceOutput; }
      62           0 :     bool unoTypeCheck() const { return m_bUnoTypeCheck; }
      63           0 :     bool checkUnpublished() const { return m_checkUnpublished; }
      64             : 
      65             : protected:
      66             :     bool setRegName_Impl(char c, std::string const & param);
      67             : 
      68             :     virtual void printUsage_Impl() const SAL_OVERRIDE;
      69             :     virtual bool initOptions_Impl (std::vector< std::string > & rArgs) SAL_OVERRIDE;
      70             : 
      71             :     std::string m_regName1;
      72             :     std::string m_regName2;
      73             :     OUString    m_startKey;
      74             :     StringSet   m_excludeKeys;
      75             :     bool m_bFullCheck;
      76             :     bool m_bForceOutput;
      77             :     bool m_bUnoTypeCheck;
      78             :     bool m_checkUnpublished;
      79             : };
      80             : 
      81             : #define U2S( s ) OUStringToOString(s, RTL_TEXTENCODING_UTF8).getStr()
      82             : 
      83           0 : inline OUString makeOUString (std::string const & s)
      84             : {
      85           0 :     return OUString(s.c_str(), s.size(), RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
      86             : }
      87             : 
      88           0 : inline OUString shortName(OUString const & fullName)
      89             : {
      90           0 :     return fullName.copy(fullName.lastIndexOf('/') + 1);
      91             : }
      92             : 
      93           0 : bool Options_Impl::setRegName_Impl(char c, std::string const & param)
      94             : {
      95           0 :     bool one = (c == '1'), two = (c == '2');
      96           0 :     if (one)
      97           0 :         m_regName1 = param;
      98           0 :     if (two)
      99           0 :         m_regName2 = param;
     100           0 :     return (one || two);
     101             : }
     102             : 
     103             : //virtual
     104           0 : void Options_Impl::printUsage_Impl() const
     105             : {
     106           0 :     std::string const & rProgName = getProgramName();
     107             :     fprintf(stderr,
     108             :             "Usage: %s -r1<filename> -r2<filename> [-options] | @<filename>\n", rProgName.c_str()
     109           0 :             );
     110             :     fprintf(stderr,
     111             :             "    -r1<filename>  = filename specifies the name of the first registry.\n"
     112             :             "    -r2<filename>  = filename specifies the name of the second registry.\n"
     113             :             "    @<filename>    = filename specifies a command file.\n"
     114             :             "Options:\n"
     115             :             "    -s<name>  = name specifies the name of a start key. If no start key\n"
     116             :             "     |S<name>   is specified the comparison starts with the root key.\n"
     117             :             "    -x<name>  = name specifies the name of a key which won't be compared. All\n"
     118             :             "     |X<name>   subkeys won't be compared also. This option can be used more than once.\n"
     119             :             "    -f|F      = force the detailed output of any diffenrences. Default\n"
     120             :             "                is that only the number of differences is returned.\n"
     121             :             "    -c|C      = make a complete check, that means any differences will be\n"
     122             :             "                detected. Default is only a compatibility check that means\n"
     123             :             "                only UNO typelibrary entries will be checked.\n"
     124             :             "    -t|T      = make an UNO type compatiblity check. This means that registry 2\n"
     125             :             "                will be checked against registry 1. If a interface in r2 contains\n"
     126             :             "                more methods or the methods are in a different order as in r1, r2 is\n"
     127             :             "                incompatible to r1. But if a service in r2 supports more properties as\n"
     128             :             "                in r1 and the new properties are 'optional' it is compatible.\n"
     129             :             "    -u|U      = additionally check types that are unpublished in registry 1.\n"
     130             :             "    -h|-?     = print this help message and exit.\n"
     131           0 :             );
     132             :     fprintf(stderr,
     133             :             "\n%s Version 1.0\n\n", rProgName.c_str()
     134           0 :             );
     135           0 : }
     136             : 
     137             : // virtual
     138           0 : bool Options_Impl::initOptions_Impl (std::vector< std::string > & rArgs)
     139             : {
     140           0 :     std::vector< std::string >::const_iterator first = rArgs.begin(), last = rArgs.end();
     141           0 :     for (; first != last; ++first)
     142             :     {
     143           0 :         if ((*first)[0] != '-')
     144             :         {
     145           0 :             return badOption("invalid", (*first).c_str());
     146             :         }
     147           0 :         switch ((*first)[1])
     148             :         {
     149             :         case 'r':
     150             :         case 'R':
     151             :             {
     152           0 :                 if (!((++first != last) && ((*first)[0] != '-')))
     153             :                 {
     154           0 :                     return badOption("invalid", (*first).c_str());
     155             :                 }
     156             : 
     157           0 :                 std::string option(*first), param;
     158           0 :                 if (option.size() == 1)
     159             :                 {
     160             :                     // "-r<n><space><param>"
     161           0 :                     if (!((++first != last) && ((*first)[0] != '-')))
     162             :                     {
     163           0 :                         return badOption("invalid", (*first).c_str());
     164             :                     }
     165           0 :                     param = (*first);
     166             :                 }
     167             :                 else
     168             :                 {
     169             :                     // "-r<n><param>"
     170           0 :                     param = std::string(&(option[1]), option.size() - 1);
     171             :                 }
     172           0 :                 if (!setRegName_Impl(option[0], param))
     173             :                 {
     174           0 :                     return badOption("invalid", option.c_str());
     175             :                 }
     176           0 :                 break;
     177             :             }
     178             :         case 's':
     179             :         case 'S':
     180             :             {
     181           0 :                 if (!((++first != last) && ((*first)[0] != '-')))
     182             :                 {
     183           0 :                     return badOption("invalid", (*first).c_str());
     184             :                 }
     185           0 :                 m_startKey = makeOUString(*first);
     186           0 :                 break;
     187             :             }
     188             :         case 'x':
     189             :         case 'X':
     190             :             {
     191           0 :                 if (!((++first != last) && ((*first)[0] != '-')))
     192             :                 {
     193           0 :                     return badOption("invalid", (*first).c_str());
     194             :                 }
     195           0 :                 m_excludeKeys.insert(makeOUString(*first));
     196           0 :                 break;
     197             :             }
     198             :         case 'f':
     199             :         case 'F':
     200             :             {
     201           0 :                 if ((*first).size() > 2)
     202             :                 {
     203           0 :                     return badOption("invalid", (*first).c_str());
     204             :                 }
     205           0 :                 m_bForceOutput = true;
     206           0 :                 break;
     207             :             }
     208             :         case 'c':
     209             :         case 'C':
     210             :             {
     211           0 :                 if ((*first).size() > 2)
     212             :                 {
     213           0 :                     return badOption("invalid", (*first).c_str());
     214             :                 }
     215           0 :                 m_bFullCheck = true;
     216           0 :                 break;
     217             :             }
     218             :         case 't':
     219             :         case 'T':
     220             :             {
     221           0 :                 if ((*first).size() > 2)
     222             :                 {
     223           0 :                     return badOption("invalid", (*first).c_str());
     224             :                 }
     225           0 :                 m_bUnoTypeCheck = true;
     226           0 :                 break;
     227             :             }
     228             :         case 'u':
     229             :         case 'U':
     230             :             {
     231           0 :                 if ((*first).size() > 2)
     232             :                 {
     233           0 :                     return badOption("invalid", (*first).c_str());
     234             :                 }
     235           0 :                 m_checkUnpublished = true;
     236           0 :                 break;
     237             :             }
     238             :         case 'h':
     239             :         case '?':
     240             :             {
     241           0 :                 if ((*first).size() > 2)
     242             :                 {
     243           0 :                     return badOption("invalid", (*first).c_str());
     244             :                 }
     245           0 :                 return printUsage();
     246             :                 // break; // Unreachable
     247             :             }
     248             :         default:
     249             :             {
     250           0 :                 return badOption("unknown", (*first).c_str());
     251             :                 // break; // Unreachable
     252             :             }
     253             :         }
     254             :     }
     255             : 
     256           0 :     if ( m_regName1.empty() )
     257             :     {
     258           0 :         return badOption("missing", "-r1");
     259             :     }
     260           0 :     if ( m_regName2.empty() )
     261             :     {
     262           0 :         return badOption("missing", "-r2");
     263             :     }
     264           0 :     return true;
     265             : }
     266             : 
     267           0 : bool Options_Impl::matchedWithExcludeKey( const OUString& keyName) const
     268             : {
     269           0 :     if (!m_excludeKeys.empty())
     270             :     {
     271           0 :         StringSet::const_iterator first = m_excludeKeys.begin(), last = m_excludeKeys.end();
     272           0 :         for (; first != last; ++first)
     273             :         {
     274           0 :             if (keyName.startsWith(*first))
     275           0 :                 return true;
     276             :         }
     277             :     }
     278           0 :     return false;
     279             : }
     280             : 
     281           0 : static char const * getTypeClass(RTTypeClass typeClass)
     282             : {
     283           0 :     switch (typeClass)
     284             :     {
     285             :         case RT_TYPE_INTERFACE:
     286           0 :             return "INTERFACE";
     287             :         case RT_TYPE_MODULE:
     288           0 :             return "MODULE";
     289             :         case RT_TYPE_STRUCT:
     290           0 :             return "STRUCT";
     291             :         case RT_TYPE_ENUM:
     292           0 :             return "ENUM";
     293             :         case RT_TYPE_EXCEPTION:
     294           0 :             return "EXCEPTION";
     295             :         case RT_TYPE_TYPEDEF:
     296           0 :             return "TYPEDEF";
     297             :         case RT_TYPE_SERVICE:
     298           0 :             return "SERVICE";
     299             :         case RT_TYPE_OBJECT:
     300           0 :             return "OBJECT";
     301             :         case RT_TYPE_CONSTANTS:
     302           0 :             return "CONSTANTS";
     303             :         default:
     304           0 :             return "INVALID";
     305             :     }
     306             : }
     307             : 
     308           0 : static OString getFieldAccess(RTFieldAccess fieldAccess)
     309             : {
     310           0 :     OString ret;
     311             :     if ( (fieldAccess & RT_ACCESS_INVALID) == RT_ACCESS_INVALID )
     312             :     {
     313           0 :         ret += OString("INVALID");
     314             :     }
     315           0 :     if ( (fieldAccess & RT_ACCESS_READONLY) == RT_ACCESS_READONLY )
     316             :     {
     317           0 :         ret += OString(ret.isEmpty() ? "READONLY" : ",READONLY");
     318             :     }
     319           0 :     if ( (fieldAccess & RT_ACCESS_OPTIONAL) == RT_ACCESS_OPTIONAL )
     320             :     {
     321           0 :         ret += OString(ret.isEmpty() ? "OPTIONAL" : ",OPTIONAL");
     322             :     }
     323           0 :     if ( (fieldAccess & RT_ACCESS_MAYBEVOID) == RT_ACCESS_MAYBEVOID )
     324             :     {
     325           0 :         ret += OString(ret.isEmpty() ? "MAYBEVOID" : ",MAYBEVOID");
     326             :     }
     327           0 :     if ( (fieldAccess & RT_ACCESS_BOUND) == RT_ACCESS_BOUND )
     328             :     {
     329           0 :         ret += OString(ret.isEmpty() ? "BOUND" : ",BOUND");
     330             :     }
     331           0 :     if ( (fieldAccess & RT_ACCESS_CONSTRAINED) == RT_ACCESS_CONSTRAINED )
     332             :     {
     333           0 :         ret += OString(ret.isEmpty() ? "CONSTRAINED" : ",CONSTRAINED");
     334             :     }
     335           0 :     if ( (fieldAccess & RT_ACCESS_TRANSIENT) == RT_ACCESS_TRANSIENT )
     336             :     {
     337           0 :         ret += OString(ret.isEmpty() ? "TRANSIENT" : ",TRANSIENT");
     338             :     }
     339           0 :     if ( (fieldAccess & RT_ACCESS_MAYBEAMBIGUOUS) == RT_ACCESS_MAYBEAMBIGUOUS )
     340             :     {
     341           0 :         ret += OString(ret.isEmpty() ? "MAYBEAMBIGUOUS" : ",MAYBEAMBIGUOUS");
     342             :     }
     343           0 :     if ( (fieldAccess & RT_ACCESS_MAYBEDEFAULT) == RT_ACCESS_MAYBEDEFAULT )
     344             :     {
     345           0 :         ret += OString(ret.isEmpty() ? "MAYBEDEFAULT" : ",MAYBEDEFAULT");
     346             :     }
     347           0 :     if ( (fieldAccess & RT_ACCESS_REMOVABLE) == RT_ACCESS_REMOVABLE )
     348             :     {
     349           0 :         ret += OString(ret.isEmpty() ? "REMOVABLE" : ",REMOVABLE");
     350             :     }
     351           0 :     if ( (fieldAccess & RT_ACCESS_ATTRIBUTE) == RT_ACCESS_ATTRIBUTE )
     352             :     {
     353           0 :         ret += OString(ret.isEmpty() ? "ATTRIBUTE" : ",ATTRIBUTE");
     354             :     }
     355           0 :     if ( (fieldAccess & RT_ACCESS_PROPERTY) == RT_ACCESS_PROPERTY )
     356             :     {
     357           0 :         ret += OString(ret.isEmpty() ? "PROPERTY" : ",PROPERTY");
     358             :     }
     359           0 :     if ( (fieldAccess & RT_ACCESS_CONST) == RT_ACCESS_CONST )
     360             :     {
     361           0 :         ret += OString(ret.isEmpty() ? "CONST" : ",CONST");
     362             :     }
     363           0 :     if ( (fieldAccess & RT_ACCESS_READWRITE) == RT_ACCESS_READWRITE )
     364             :     {
     365           0 :         ret += OString(ret.isEmpty() ? "READWRITE" : ",READWRITE");
     366             :     }
     367           0 :     return ret;
     368             : }
     369             : 
     370           0 : static char const * getConstValueType(RTConstValue& constValue)
     371             : {
     372           0 :     switch (constValue.m_type)
     373             :     {
     374             :         case RT_TYPE_BOOL:
     375           0 :             return "sal_Bool";
     376             :         case RT_TYPE_BYTE:
     377           0 :             return "sal_uInt8";
     378             :         case RT_TYPE_INT16:
     379           0 :             return "sal_Int16";
     380             :         case RT_TYPE_UINT16:
     381           0 :             return "sal_uInt16";
     382             :         case RT_TYPE_INT32:
     383           0 :             return "sal_Int32";
     384             :         case RT_TYPE_UINT32:
     385           0 :             return "sal_uInt32";
     386             : //      case RT_TYPE_INT64:
     387             : //          return "sal_Int64";
     388             : //      case RT_TYPE_UINT64:
     389             : //          return "sal_uInt64";
     390             :         case RT_TYPE_FLOAT:
     391           0 :             return "float";
     392             :         case RT_TYPE_DOUBLE:
     393           0 :             return "double";
     394             :         case RT_TYPE_STRING:
     395           0 :             return "sal_Unicode*";
     396             :         default:
     397           0 :             return "NONE";
     398             :     }
     399             : }
     400             : 
     401           0 : static void printConstValue(RTConstValue& constValue)
     402             : {
     403           0 :     switch (constValue.m_type)
     404             :     {
     405             :         case RT_TYPE_NONE:
     406           0 :             fprintf(stdout, "none");
     407           0 :             break;
     408             :         case RT_TYPE_BOOL:
     409           0 :             fprintf(stdout, "%s", constValue.m_value.aBool ? "TRUE" : "FALSE");
     410           0 :             break;
     411             :         case RT_TYPE_BYTE:
     412           0 :             fprintf(stdout, "%d", constValue.m_value.aByte);
     413           0 :             break;
     414             :         case RT_TYPE_INT16:
     415           0 :             fprintf(stdout, "%d", constValue.m_value.aShort);
     416           0 :             break;
     417             :         case RT_TYPE_UINT16:
     418           0 :             fprintf(stdout, "%d", constValue.m_value.aUShort);
     419           0 :             break;
     420             :         case RT_TYPE_INT32:
     421             :             fprintf(
     422             :                 stdout, "%ld",
     423           0 :                 sal::static_int_cast< long >(constValue.m_value.aLong));
     424           0 :             break;
     425             :         case RT_TYPE_UINT32:
     426             :             fprintf(
     427             :                 stdout, "%lu",
     428             :                 sal::static_int_cast< unsigned long >(
     429           0 :                     constValue.m_value.aULong));
     430           0 :             break;
     431             : //      case RT_TYPE_INT64:
     432             : //          fprintf(stdout, "%d", constValue.m_value.aHyper);
     433             : //      case RT_TYPE_UINT64:
     434             : //          fprintf(stdout, "%d", constValue.m_value.aUHyper);
     435             :         case RT_TYPE_FLOAT:
     436           0 :             fprintf(stdout, "%f", constValue.m_value.aFloat);
     437           0 :             break;
     438             :         case RT_TYPE_DOUBLE:
     439           0 :             fprintf(stdout, "%f", constValue.m_value.aDouble);
     440           0 :             break;
     441             :         case RT_TYPE_STRING:
     442             :             fprintf(
     443             :                 stdout, "%s",
     444             :                 (OUStringToOString(
     445             :                     constValue.m_value.aString, RTL_TEXTENCODING_UTF8).
     446           0 :                  getStr()));
     447           0 :             break;
     448             :         default:
     449           0 :             break;
     450             :     }
     451           0 : }
     452             : 
     453           0 : static void dumpTypeClass(bool & rbDump, RTTypeClass typeClass, OUString const & keyName)
     454             : {
     455           0 :     if (rbDump)
     456           0 :         fprintf(stdout, "%s: %s\n", getTypeClass(typeClass), U2S(keyName));
     457           0 :     rbDump = false;
     458           0 : }
     459             : 
     460           0 : static sal_uInt32 checkConstValue(Options_Impl const & options,
     461             :                                   const OUString& keyName,
     462             :                                   RTTypeClass typeClass,
     463             :                                   bool & bDump,
     464             :                                   RTConstValue& constValue1,
     465             :                                   RTConstValue& constValue2,
     466             :                                   sal_uInt16 index1)
     467             : {
     468           0 :     switch (constValue1.m_type)
     469             :     {
     470             :         case RT_TYPE_NONE:
     471           0 :             break;
     472             :         case RT_TYPE_BOOL:
     473           0 :             if (constValue1.m_value.aBool != constValue2.m_value.aBool)
     474             :             {
     475           0 :                 if ( options.forceOutput() && !options.unoTypeCheck() )
     476             :                 {
     477           0 :                     dumpTypeClass(bDump, typeClass, keyName);
     478             :                     fprintf(stdout, "  Field %d: Value1 = %s  !=  Value2 = %s\n", index1,
     479             :                             constValue1.m_value.aBool ? "TRUE" : "FALSE",
     480           0 :                             constValue2.m_value.aBool ? "TRUE" : "FALSE");
     481             :                 }
     482           0 :                 return 1;
     483             :             }
     484           0 :             break;
     485             :         case RT_TYPE_BYTE:
     486           0 :             if (constValue1.m_value.aByte != constValue2.m_value.aByte)
     487             :             {
     488           0 :                 if ( options.forceOutput() && !options.unoTypeCheck() )
     489             :                 {
     490           0 :                     dumpTypeClass(bDump, typeClass, keyName);
     491             :                     fprintf(stdout, "  Field %d: Value1 = %d  !=  Value2 = %d\n", index1,
     492           0 :                             constValue1.m_value.aByte, constValue2.m_value.aByte);
     493             :                 }
     494           0 :                 return 1;
     495             :             }
     496           0 :             break;
     497             :         case RT_TYPE_INT16:
     498           0 :             if (constValue1.m_value.aShort != constValue2.m_value.aShort)
     499             :             {
     500           0 :                 if ( options.forceOutput() && !options.unoTypeCheck() )
     501             :                 {
     502           0 :                     dumpTypeClass(bDump, typeClass, keyName);
     503             :                     fprintf(stdout, "  Field %d: Value1 = %d  !=  Value2 = %d\n", index1,
     504           0 :                             constValue1.m_value.aShort, constValue2.m_value.aShort);
     505             :                 }
     506           0 :                 return 1;
     507             :             }
     508           0 :             break;
     509             :         case RT_TYPE_UINT16:
     510           0 :             if (constValue1.m_value.aUShort != constValue2.m_value.aUShort)
     511             :             {
     512           0 :                 if ( options.forceOutput() && !options.unoTypeCheck() )
     513             :                 {
     514           0 :                     dumpTypeClass(bDump, typeClass, keyName);
     515             :                     fprintf(stdout, "  Field %d: Value1 = %d  !=  Value2 = %d\n", index1,
     516           0 :                             constValue1.m_value.aUShort, constValue2.m_value.aUShort);
     517             :                 }
     518           0 :                 return 1;
     519             :             }
     520           0 :             break;
     521             :         case RT_TYPE_INT32:
     522           0 :             if (constValue1.m_value.aLong != constValue2.m_value.aLong)
     523             :             {
     524           0 :                 if ( options.forceOutput() && !options.unoTypeCheck() )
     525             :                 {
     526           0 :                     dumpTypeClass(bDump, typeClass, keyName);
     527             :                     fprintf(stdout, "  Field %d: Value1 = %ld  !=  Value2 = %ld\n", index1,
     528             :                             sal::static_int_cast< long >(constValue1.m_value.aLong),
     529           0 :                             sal::static_int_cast< long >(constValue2.m_value.aLong));
     530             :                 }
     531           0 :                 return 1;
     532             :             }
     533           0 :             break;
     534             :         case RT_TYPE_UINT32:
     535           0 :             if (constValue1.m_value.aULong != constValue2.m_value.aULong)
     536             :             {
     537           0 :                 if ( options.forceOutput() && !options.unoTypeCheck() )
     538             :                 {
     539           0 :                     dumpTypeClass(bDump, typeClass, keyName);
     540             :                     fprintf(stdout, "  Field %d: Value1 = %lu  !=  Value2 = %lu\n", index1,
     541             :                             sal::static_int_cast< unsigned long >(constValue1.m_value.aULong),
     542           0 :                             sal::static_int_cast< unsigned long >(constValue2.m_value.aULong));
     543             :                 }
     544           0 :                 return 1;
     545             :             }
     546           0 :             break;
     547             :         case RT_TYPE_INT64:
     548           0 :             if (constValue1.m_value.aHyper != constValue2.m_value.aHyper)
     549             :             {
     550           0 :                 if ( options.forceOutput() && !options.unoTypeCheck() )
     551             :                 {
     552           0 :                     dumpTypeClass(bDump, typeClass, keyName);
     553             :                     fprintf(
     554             :                         stdout, "  Field %d: Value1 = %s  !=  Value2 = %s\n",
     555             :                         index1,
     556             :                         OUStringToOString(
     557             :                             OUString::number(constValue1.m_value.aHyper),
     558             :                             RTL_TEXTENCODING_ASCII_US).getStr(),
     559             :                         OUStringToOString(
     560             :                             OUString::number(constValue2.m_value.aHyper),
     561           0 :                             RTL_TEXTENCODING_ASCII_US).getStr());
     562             :                 }
     563           0 :                 return 1;
     564             :             }
     565           0 :             break;
     566             :         case RT_TYPE_UINT64:
     567           0 :             if (constValue1.m_value.aUHyper != constValue2.m_value.aUHyper)
     568             :             {
     569           0 :                 if ( options.forceOutput() && !options.unoTypeCheck() )
     570             :                 {
     571           0 :                     dumpTypeClass(bDump, typeClass, keyName);
     572             :                     fprintf(
     573             :                         stdout, "  Field %d: Value1 = %s  !=  Value2 = %s\n",
     574             :                         index1,
     575             :                         OUStringToOString(
     576             :                             OUString::number(
     577             :                                 constValue1.m_value.aUHyper),
     578             :                             RTL_TEXTENCODING_ASCII_US).getStr(),
     579             :                         OUStringToOString(
     580             :                             OUString::number(
     581             :                                 constValue2.m_value.aUHyper),
     582           0 :                             RTL_TEXTENCODING_ASCII_US).getStr());
     583             :                         // printing the unsigned values as signed should be
     584             :                         // acceptable...
     585             :                 }
     586           0 :                 return 1;
     587             :             }
     588           0 :             break;
     589             :         case RT_TYPE_FLOAT:
     590           0 :             if (constValue1.m_value.aFloat != constValue2.m_value.aFloat)
     591             :             {
     592           0 :                 if ( options.forceOutput() && !options.unoTypeCheck() )
     593             :                 {
     594           0 :                     dumpTypeClass(bDump, typeClass, keyName);
     595             :                     fprintf(stdout, "  Field %d: Value1 = %f  !=  Value2 = %f\n", index1,
     596           0 :                             constValue1.m_value.aFloat, constValue2.m_value.aFloat);
     597             :                 }
     598           0 :                 return 1;
     599             :             }
     600           0 :             break;
     601             :         case RT_TYPE_DOUBLE:
     602           0 :             if (constValue1.m_value.aDouble != constValue2.m_value.aDouble)
     603             :             {
     604           0 :                 if ( options.forceOutput() && !options.unoTypeCheck() )
     605             :                 {
     606           0 :                     dumpTypeClass(bDump, typeClass, keyName);
     607             :                     fprintf(stdout, "  Field %d: Value1 = %f  !=  Value2 = %f\n", index1,
     608           0 :                             constValue1.m_value.aDouble, constValue2.m_value.aDouble);
     609             :                 }
     610           0 :                 return 1;
     611             :             }
     612           0 :             break;
     613             :         default:
     614             :             OSL_ASSERT(false);
     615           0 :             break;
     616             :     }
     617           0 :     return 0;
     618             : }
     619             : 
     620             : enum verbosity_t {SILENT, REPORT};
     621           0 : static sal_uInt32 checkField(Options_Impl const & options,
     622             :                              const OUString& keyName,
     623             :                              RTTypeClass typeClass,
     624             :                              bool & bDump,
     625             :                              typereg::Reader& reader1,
     626             :                              typereg::Reader& reader2,
     627             :                              sal_uInt16 index1,
     628             :                              sal_uInt16 index2,
     629             :                              verbosity_t const eVerbosity)
     630             : {
     631           0 :     sal_uInt32 nError = 0;
     632           0 :     if ( reader1.getFieldName(index1) != reader2.getFieldName(index2) )
     633             :     {
     634           0 :         if (options.forceOutput() && (REPORT == eVerbosity))
     635             :         {
     636           0 :             dumpTypeClass (bDump, typeClass, keyName);
     637             :             fprintf(stdout, "  Field %d: Name1 = %s  !=  Name2 = %s\n", index1,
     638           0 :                     U2S(reader1.getFieldName(index1)), U2S(reader2.getFieldName(index2)));
     639             :         }
     640           0 :         nError++;
     641             :     }
     642           0 :     if ( reader1.getFieldTypeName(index1) != reader2.getFieldTypeName(index2) )
     643             :     {
     644           0 :         if (options.forceOutput() && (REPORT == eVerbosity))
     645             :         {
     646           0 :             dumpTypeClass (bDump, typeClass, keyName);
     647             :             fprintf(stdout, "  Field %d: Type1 = %s  !=  Type2 = %s\n", index1,
     648           0 :                     U2S(reader1.getFieldTypeName(index1)), U2S(reader2.getFieldTypeName(index2)));
     649             :         }
     650           0 :         nError++;
     651             :     }
     652             :     else
     653             :     {
     654           0 :         RTConstValue constValue1 = reader1.getFieldValue(index1);
     655           0 :         RTConstValue constValue2 = reader2.getFieldValue(index2);
     656           0 :         if ( constValue1.m_type != constValue2.m_type )
     657             :         {
     658           0 :             if (options.forceOutput() && (REPORT == eVerbosity))
     659             :             {
     660           0 :                 dumpTypeClass (bDump, typeClass, keyName);
     661             :                 fprintf(stdout, "  Field %d: Access1 = %s  !=  Access2 = %s\n", index1,
     662           0 :                         getConstValueType(constValue1), getConstValueType(constValue2));
     663           0 :                 fprintf(stdout, "  Field %d: Value1 = ", index1);
     664           0 :                 printConstValue(constValue1);
     665           0 :                 fprintf(stdout, "  !=  Value2 = ");
     666           0 :                 printConstValue(constValue1);
     667           0 :                 fprintf(stdout, "\n;");
     668             :             }
     669           0 :             nError++;
     670             :         }
     671             :         else
     672             :         {
     673           0 :             nError += checkConstValue(options, keyName, typeClass, bDump, constValue1, constValue2, index1);
     674           0 :         }
     675             :     }
     676             : 
     677           0 :     if ( reader1.getFieldFlags(index1) != reader2.getFieldFlags(index2) )
     678             :     {
     679           0 :         if (options.forceOutput() && (REPORT == eVerbosity))
     680             :         {
     681           0 :             dumpTypeClass (bDump, typeClass, keyName);
     682             :             fprintf(stdout, "  Field %d: FieldAccess1 = %s  !=  FieldAccess2 = %s\n", index1,
     683           0 :                     getFieldAccess(reader1.getFieldFlags(index1)).getStr(),
     684           0 :                     getFieldAccess(reader1.getFieldFlags(index2)).getStr());
     685             :         }
     686           0 :         nError++;
     687             :     }
     688             : 
     689           0 :     if ( options.fullCheck() && (reader1.getFieldDocumentation(index1) != reader2.getFieldDocumentation(index2)) )
     690             :     {
     691           0 :         if (options.forceOutput() && (REPORT == eVerbosity))
     692             :         {
     693           0 :             dumpTypeClass (bDump, typeClass, keyName);
     694             :             fprintf(stdout, "  Field %d: Doku1 = %s\n             Doku2 = %s\n", index1,
     695           0 :                     U2S(reader1.getFieldDocumentation(index1)), U2S(reader2.getFieldDocumentation(index2)));
     696             :         }
     697           0 :         nError++;
     698             :     }
     699           0 :     return nError;
     700             : }
     701             : 
     702           0 : static char const * getMethodMode(RTMethodMode methodMode)
     703             : {
     704           0 :     switch ( methodMode )
     705             :     {
     706             :         case RT_MODE_ONEWAY:
     707           0 :             return "ONEWAY";
     708             :         case RT_MODE_ONEWAY_CONST:
     709           0 :             return "ONEWAY,CONST";
     710             :         case RT_MODE_TWOWAY:
     711           0 :             return "NONE";
     712             :         case RT_MODE_TWOWAY_CONST:
     713           0 :             return "CONST";
     714             :         default:
     715           0 :             return "INVALID";
     716             :     }
     717             : }
     718             : 
     719           0 : static char const * getParamMode(RTParamMode paramMode)
     720             : {
     721           0 :     switch ( paramMode )
     722             :     {
     723             :         case RT_PARAM_IN:
     724           0 :             return "IN";
     725             :         case RT_PARAM_OUT:
     726           0 :             return "OUT";
     727             :         case RT_PARAM_INOUT:
     728           0 :             return "INOUT";
     729             :         default:
     730           0 :             return "INVALID";
     731             :     }
     732             : }
     733             : 
     734           0 : static sal_uInt32 checkMethod(Options_Impl const & options,
     735             :                               const OUString& keyName,
     736             :                               RTTypeClass typeClass,
     737             :                               bool & bDump,
     738             :                               typereg::Reader& reader1,
     739             :                               typereg::Reader& reader2,
     740             :                               sal_uInt16 index)
     741             : {
     742           0 :     sal_uInt32 nError = 0;
     743           0 :     if ( reader1.getMethodName(index) != reader2.getMethodName(index) )
     744             :     {
     745           0 :         if ( options.forceOutput() )
     746             :         {
     747           0 :             dumpTypeClass (bDump, typeClass, keyName);
     748             :             fprintf(stdout, "  Method1 %d: Name1 = %s  !=  Name2 = %s\n", index,
     749             :                     U2S(reader1.getMethodName(index)),
     750           0 :                     U2S(reader2.getMethodName(index)));
     751             :         }
     752           0 :         nError++;
     753             :     }
     754             : 
     755           0 :     if ( reader1.getMethodReturnTypeName(index) != reader2.getMethodReturnTypeName(index) )
     756             :     {
     757           0 :         if ( options.forceOutput() )
     758             :         {
     759           0 :             dumpTypeClass (bDump, typeClass, keyName);
     760             :             fprintf(stdout, "  Method1 %d: ReturnType1 = %s  !=  ReturnType2 = %s\n", index,
     761             :                     U2S(reader1.getMethodReturnTypeName(index)),
     762           0 :                     U2S(reader2.getMethodReturnTypeName(index)));
     763             :         }
     764           0 :         nError++;
     765             :     }
     766             : 
     767           0 :     sal_uInt16 nParams1 = (sal_uInt16)reader1.getMethodParameterCount(index);
     768           0 :     sal_uInt16 nParams2 = (sal_uInt16)reader2.getMethodParameterCount(index);
     769           0 :     if ( nParams1 != nParams2 )
     770             :     {
     771           0 :         if ( options.forceOutput() )
     772             :         {
     773           0 :             dumpTypeClass (bDump, typeClass, keyName);
     774           0 :             fprintf(stdout, "  Method %d : nParameters1 = %d  !=  nParameters2 = %d\n", index, nParams1, nParams2);
     775             :         }
     776           0 :         nError++;
     777             :     }
     778           0 :     sal_uInt16 i=0;
     779           0 :     for (i=0; i < nParams1 && i < nParams2; i++)
     780             :     {
     781           0 :         if ( reader1.getMethodParameterTypeName(index, i) != reader2.getMethodParameterTypeName(index, i) )
     782             :         {
     783           0 :             if ( options.forceOutput() )
     784             :             {
     785           0 :                 dumpTypeClass (bDump, typeClass, keyName);
     786             :                 fprintf(stdout, "  Method %d, Parameter %d: Type1 = %s  !=  Type2 = %s\n", index, i,
     787             :                         U2S(reader1.getMethodParameterTypeName(index, i)),
     788           0 :                         U2S(reader2.getMethodParameterTypeName(index, i)));
     789             :             }
     790           0 :             nError++;
     791             :         }
     792           0 :         if ( options.fullCheck() && (reader1.getMethodParameterName(index, i) != reader2.getMethodParameterName(index, i)) )
     793             :         {
     794           0 :             if ( options.forceOutput() )
     795             :             {
     796           0 :                 dumpTypeClass (bDump, typeClass, keyName);
     797             :                 fprintf(stdout, "  Method %d, Parameter %d: Name1 = %s  !=  Name2 = %s\n", index, i,
     798             :                         U2S(reader1.getMethodParameterName(index, i)),
     799           0 :                         U2S(reader2.getMethodParameterName(index, i)));
     800             :             }
     801           0 :             nError++;
     802             :         }
     803           0 :         if ( reader1.getMethodParameterFlags(index, i) != reader2.getMethodParameterFlags(index, i) )
     804             :         {
     805           0 :             if ( options.forceOutput() )
     806             :             {
     807           0 :                 dumpTypeClass (bDump, typeClass, keyName);
     808             :                 fprintf(stdout, "  Method %d, Parameter %d: Mode1 = %s  !=  Mode2 = %s\n", index, i,
     809             :                         getParamMode(reader1.getMethodParameterFlags(index, i)),
     810           0 :                         getParamMode(reader2.getMethodParameterFlags(index, i)));
     811             :             }
     812           0 :             nError++;
     813             :         }
     814             :     }
     815           0 :     if ( i < nParams1 && options.forceOutput() )
     816             :     {
     817           0 :         dumpTypeClass (bDump, typeClass, keyName);
     818           0 :         fprintf(stdout, "  Registry1: Method %d contains %d more parameters\n", index, nParams1 - i);
     819             :     }
     820           0 :     if ( i < nParams2 && options.forceOutput() )
     821             :     {
     822           0 :         dumpTypeClass (bDump, typeClass, keyName);
     823           0 :         fprintf(stdout, "  Registry2: Method %d contains %d more parameters\n", index, nParams2 - i);
     824             :     }
     825             : 
     826           0 :     sal_uInt16 nExcep1 = (sal_uInt16)reader1.getMethodExceptionCount(index);
     827           0 :     sal_uInt16 nExcep2 = (sal_uInt16)reader2.getMethodExceptionCount(index);
     828           0 :     if ( nExcep1 != nExcep2 )
     829             :     {
     830           0 :         if ( options.forceOutput() )
     831             :         {
     832           0 :             dumpTypeClass (bDump, typeClass, keyName);
     833           0 :             fprintf(stdout, "  nExceptions1 = %d  !=  nExceptions2 = %d\n", nExcep1, nExcep2);
     834             :         }
     835           0 :         nError++;
     836             :     }
     837           0 :     for (i=0; i < nExcep1 && i < nExcep2; i++)
     838             :     {
     839           0 :         if ( reader1.getMethodExceptionTypeName(index, i) != reader2.getMethodExceptionTypeName(index, i) )
     840             :         {
     841           0 :             if ( options.forceOutput() )
     842             :             {
     843           0 :                 dumpTypeClass (bDump, typeClass, keyName);
     844             :                 fprintf(stdout, "  Method %d, Exception %d: Name1 = %s  !=  Name2 = %s\n", index, i,
     845             :                         U2S(reader1.getMethodExceptionTypeName(index, i)),
     846           0 :                         U2S(reader2.getMethodExceptionTypeName(index, i)));
     847             :             }
     848           0 :             nError++;
     849             :         }
     850             :     }
     851           0 :     if ( i < nExcep1 && options.forceOutput() )
     852             :     {
     853           0 :         dumpTypeClass (bDump, typeClass, keyName);
     854           0 :         fprintf(stdout, "  Registry1: Method %d contains %d more exceptions\n", index, nExcep1 - i);
     855             :     }
     856           0 :     if ( i < nExcep2 && options.forceOutput() )
     857             :     {
     858           0 :         dumpTypeClass (bDump, typeClass, keyName);
     859           0 :         fprintf(stdout, "  Registry2: Method %d contains %d more exceptions\n", index, nExcep2 - i);
     860             :     }
     861             : 
     862           0 :     if ( reader1.getMethodFlags(index) != reader2.getMethodFlags(index) )
     863             :     {
     864           0 :         if ( options.forceOutput() )
     865             :         {
     866           0 :             dumpTypeClass (bDump, typeClass, keyName);
     867             :             fprintf(stdout, "  Method %d: Mode1 = %s  !=  Mode2 = %s\n", index,
     868             :                     getMethodMode(reader1.getMethodFlags(index)),
     869           0 :                     getMethodMode(reader2.getMethodFlags(index)));
     870             :         }
     871           0 :         nError++;
     872             :     }
     873             : 
     874           0 :     if ( options.fullCheck() && (reader1.getMethodDocumentation(index) != reader2.getMethodDocumentation(index)) )
     875             :     {
     876           0 :         if ( options.forceOutput() )
     877             :         {
     878           0 :             dumpTypeClass (bDump, typeClass, keyName);
     879             :             fprintf(stdout, "  Method %d: Doku1 = %s\n              Doku2 = %s\n", index,
     880             :                     U2S(reader1.getMethodDocumentation(index)),
     881           0 :                     U2S(reader2.getMethodDocumentation(index)));
     882             :         }
     883           0 :         nError++;
     884             :     }
     885           0 :     return nError;
     886             : }
     887             : 
     888           0 : static char const * getReferenceType(RTReferenceType refType)
     889             : {
     890           0 :     switch (refType)
     891             :     {
     892             :         case RT_REF_SUPPORTS:
     893           0 :             return "RT_REF_SUPPORTS";
     894             :         case RT_REF_OBSERVES:
     895           0 :             return "RT_REF_OBSERVES";
     896             :         case RT_REF_EXPORTS:
     897           0 :             return "RT_REF_EXPORTS";
     898             :         case RT_REF_NEEDS:
     899           0 :             return "RT_REF_NEEDS";
     900             :         default:
     901           0 :             return "RT_REF_INVALID";
     902             :     }
     903             : }
     904             : 
     905           0 : static sal_uInt32 checkReference(Options_Impl const & options,
     906             :                                  const OUString& keyName,
     907             :                                  RTTypeClass typeClass,
     908             :                                  bool & bDump,
     909             :                                  typereg::Reader& reader1,
     910             :                                     typereg::Reader& reader2,
     911             :                                     sal_uInt16 index1,
     912             :                                  sal_uInt16 index2)
     913             : {
     914           0 :     sal_uInt32 nError = 0;
     915           0 :     if ( reader1.getReferenceTypeName(index1) != reader2.getReferenceTypeName(index2) )
     916             :     {
     917           0 :         if ( options.forceOutput() && !options.unoTypeCheck() )
     918             :         {
     919           0 :             dumpTypeClass (bDump, typeClass, keyName);
     920             :             fprintf(stdout, "  Reference %d: Name1 = %s  !=  Name2 = %s\n", index1,
     921             :                     U2S(reader1.getReferenceTypeName(index1)),
     922           0 :                     U2S(reader2.getReferenceTypeName(index2)));
     923             :         }
     924           0 :         nError++;
     925             :     }
     926           0 :     if ( reader1.getReferenceTypeName(index1) != reader2.getReferenceTypeName(index2) )
     927             :     {
     928           0 :         if ( options.forceOutput() && !options.unoTypeCheck() )
     929             :         {
     930           0 :             dumpTypeClass (bDump, typeClass, keyName);
     931             :             fprintf(stdout, "  Reference %d: Type1 = %s  !=  Type2 = %s\n", index1,
     932             :                     getReferenceType(reader1.getReferenceSort(index1)),
     933           0 :                     getReferenceType(reader2.getReferenceSort(index2)));
     934             :         }
     935           0 :         nError++;
     936             :     }
     937           0 :     if ( options.fullCheck() && (reader1.getReferenceDocumentation(index1) != reader2.getReferenceDocumentation(index2)) )
     938             :     {
     939           0 :         if ( options.forceOutput() && !options.unoTypeCheck() )
     940             :         {
     941           0 :             dumpTypeClass (bDump, typeClass, keyName);
     942             :             fprintf(stdout, "  Reference %d: Doku1 = %s\n                 Doku2 = %s\n", index1,
     943             :                     U2S(reader1.getReferenceDocumentation(index1)),
     944           0 :                     U2S(reader2.getReferenceDocumentation(index2)));
     945             :         }
     946           0 :         nError++;
     947             :     }
     948           0 :     if ( reader1.getReferenceFlags(index1) != reader2.getReferenceFlags(index2) )
     949             :     {
     950           0 :         if ( options.forceOutput() && !options.unoTypeCheck() )
     951             :         {
     952           0 :             dumpTypeClass (bDump, typeClass, keyName);
     953             :             fprintf(stdout, "  Reference %d: Access1 = %s  !=  Access2 = %s\n", index1,
     954           0 :                     getFieldAccess(reader1.getReferenceFlags(index1)).getStr(),
     955           0 :                     getFieldAccess(reader1.getReferenceFlags(index2)).getStr());
     956             :         }
     957           0 :         nError++;
     958             :     }
     959           0 :     return nError;
     960             : }
     961             : 
     962           0 : static sal_uInt32 checkFieldsWithoutOrder(Options_Impl const & options,
     963             :                                           const OUString& keyName,
     964             :                                           RTTypeClass typeClass,
     965             :                                           bool & bDump,
     966             :                                           typereg::Reader& reader1,
     967             :                                           typereg::Reader& reader2)
     968             : {
     969           0 :     sal_uInt32 nError = 0;
     970             : 
     971           0 :     sal_uInt16 nFields1 = (sal_uInt16)reader1.getFieldCount();
     972           0 :     sal_uInt16 nFields2 = (sal_uInt16)reader2.getFieldCount();
     973           0 :     sal_uInt16 i=0, j=0;
     974             : 
     975           0 :     if ( nFields1 > nFields2 )
     976             :     {
     977           0 :         if ( options.forceOutput() )
     978             :         {
     979           0 :             dumpTypeClass (bDump, typeClass, keyName);
     980             :             fprintf(stdout, "  %s1 contains %d more properties as %s2\n",
     981           0 :                     getTypeClass(typeClass), nFields1-nFields2, getTypeClass(typeClass));
     982             :         }
     983             :     }
     984             : 
     985           0 :     bool bFound = false;
     986           0 :     ::std::set< sal_uInt16 > moreProps;
     987             : 
     988           0 :     for (i=0; i < nFields1; i++)
     989             :     {
     990           0 :         for (j=0; j < nFields2; j++)
     991             :         {
     992           0 :             if (!checkField(options, keyName, typeClass, bDump, reader1, reader2, i, j, SILENT))
     993             :             {
     994           0 :                 bFound =  true;
     995           0 :                 moreProps.insert(j);
     996           0 :                 break;
     997             :             }
     998             :         }
     999           0 :         if (!bFound)
    1000             :         {
    1001           0 :             if (options.forceOutput())
    1002             :             {
    1003           0 :                 dumpTypeClass (bDump, typeClass, keyName);
    1004             :                 fprintf(stdout, "  incompatible change: Field %d ('%s') of r1 is not longer a property of this %s in r2\n",
    1005           0 :                         i, U2S(shortName(reader1.getFieldName(i))), getTypeClass(typeClass));
    1006             :             }
    1007           0 :             nError++;
    1008             :         }
    1009             :         else
    1010             :         {
    1011           0 :             bFound = false;
    1012             :         }
    1013             :     }
    1014             : 
    1015           0 :     if ( typeClass == RT_TYPE_SERVICE && !moreProps.empty() )
    1016             :     {
    1017           0 :         for (j=0; j < nFields2; j++)
    1018             :         {
    1019           0 :             if ( moreProps.find(j) == moreProps.end() )
    1020             :             {
    1021           0 :                 if ( (reader2.getFieldFlags(j) & RT_ACCESS_OPTIONAL) != RT_ACCESS_OPTIONAL )
    1022             :                 {
    1023           0 :                     if ( options.forceOutput() )
    1024             :                     {
    1025           0 :                         dumpTypeClass (bDump, typeClass, keyName);
    1026             :                         fprintf(stdout,
    1027             :                                 "  incompatible change: Field %d ('%s') of r2 is a new property"
    1028             :                                 " compared to this %s in r1 and is not 'optional'\n",
    1029           0 :                                 j, U2S(shortName(reader2.getFieldName(j))), getTypeClass(typeClass));
    1030             :                     }
    1031           0 :                     nError++;
    1032             :                 }
    1033             :             }
    1034             :         }
    1035             :     }
    1036             : 
    1037           0 :     return nError;
    1038             : }
    1039             : 
    1040           0 : static sal_uInt32 checkBlob(
    1041             :     Options_Impl const & options,
    1042             :     const OUString& keyName,
    1043             :     typereg::Reader& reader1, sal_uInt32 size1,
    1044             :     typereg::Reader& reader2, sal_uInt32 size2)
    1045             : {
    1046           0 :     sal_uInt32 nError = 0;
    1047           0 :     bool bDump = true;
    1048             : 
    1049           0 :     if ( options.fullCheck() && (size1 != size2) )
    1050             :     {
    1051           0 :         if ( options.forceOutput() )
    1052             :         {
    1053             :             fprintf(
    1054             :                 stdout, "    Size1 = %lu    Size2 = %lu\n",
    1055             :                 sal::static_int_cast< unsigned long >(size1),
    1056           0 :                 sal::static_int_cast< unsigned long >(size2));
    1057             :         }
    1058             :     }
    1059           0 :     if (reader1.isPublished())
    1060             :     {
    1061           0 :         if (!reader2.isPublished())
    1062             :         {
    1063           0 :             if (options.forceOutput())
    1064             :             {
    1065           0 :                 dumpTypeClass(bDump, /*"?"*/ reader1.getTypeClass(), keyName);
    1066           0 :                 fprintf(stdout, "    published in 1 but unpublished in 2\n");
    1067             :             }
    1068           0 :             ++nError;
    1069             :         }
    1070             :     }
    1071           0 :     else if (!options.checkUnpublished())
    1072             :     {
    1073           0 :         return nError;
    1074             :     }
    1075           0 :     if ( reader1.getTypeClass() != reader2.getTypeClass() )
    1076             :     {
    1077           0 :         if ( options.forceOutput() )
    1078             :         {
    1079           0 :             dumpTypeClass(bDump, /*"?"*/ reader1.getTypeClass(), keyName);
    1080             :             fprintf(stdout, "    TypeClass1 = %s  !=  TypeClass2 = %s\n",
    1081             :                     getTypeClass(reader1.getTypeClass()),
    1082           0 :                     getTypeClass(reader2.getTypeClass()));
    1083             :         }
    1084           0 :         return ++nError;
    1085             :     }
    1086             : 
    1087           0 :     RTTypeClass typeClass = reader1.getTypeClass();
    1088           0 :     if ( reader1.getTypeName() != reader2.getTypeName() )
    1089             :     {
    1090           0 :         if ( options.forceOutput() )
    1091             :         {
    1092           0 :             dumpTypeClass(bDump, typeClass, keyName);
    1093             :             fprintf(stdout, "    TypeName1 = %s  !=  TypeName2 = %s\n",
    1094           0 :                     U2S(reader1.getTypeName()), U2S(reader2.getTypeName()));
    1095             :         }
    1096           0 :         nError++;
    1097             :     }
    1098           0 :     if ( (typeClass == RT_TYPE_INTERFACE ||
    1099           0 :           typeClass == RT_TYPE_STRUCT ||
    1100             :           typeClass == RT_TYPE_EXCEPTION) )
    1101             :     {
    1102           0 :         if (reader1.getSuperTypeCount() != reader2.getSuperTypeCount())
    1103             :         {
    1104           0 :             dumpTypeClass(bDump, typeClass, keyName);
    1105             :             fprintf(
    1106             :                 stdout, "    SuperTypeCount1 = %d  !=  SuperTypeCount2 = %d\n",
    1107           0 :                 static_cast< int >(reader1.getSuperTypeCount()),
    1108           0 :                 static_cast< int >(reader2.getSuperTypeCount()));
    1109           0 :             ++nError;
    1110             :         } else
    1111             :         {
    1112           0 :             for (sal_Int16 i = 0; i < reader1.getSuperTypeCount(); ++i)
    1113             :             {
    1114           0 :                 if (reader1.getSuperTypeName(i) != reader2.getSuperTypeName(i))
    1115             :                 {
    1116           0 :                     if ( options.forceOutput() )
    1117             :                     {
    1118           0 :                         dumpTypeClass(bDump, typeClass, keyName);
    1119             :                         fprintf(stdout, "    SuperTypeName1 = %s  !=  SuperTypeName2 = %s\n",
    1120           0 :                                 U2S(reader1.getSuperTypeName(i)), U2S(reader2.getSuperTypeName(i)));
    1121             :                     }
    1122           0 :                     nError++;
    1123             :                 }
    1124             :             }
    1125             :         }
    1126             :     }
    1127             : 
    1128           0 :     sal_uInt16 nFields1 = (sal_uInt16)reader1.getFieldCount();
    1129           0 :     sal_uInt16 nFields2 = (sal_uInt16)reader2.getFieldCount();
    1130           0 :     bool bCheckNormal = true;
    1131             : 
    1132           0 :     if ( (typeClass == RT_TYPE_SERVICE ||
    1133           0 :           typeClass == RT_TYPE_MODULE ||
    1134           0 :           typeClass == RT_TYPE_CONSTANTS) && options.unoTypeCheck() )
    1135             :     {
    1136           0 :         bCheckNormal = false;
    1137             :     }
    1138             : 
    1139           0 :     if ( bCheckNormal )
    1140             :     {
    1141           0 :         if ( nFields1 != nFields2 )
    1142             :         {
    1143           0 :             if ( options.forceOutput() )
    1144             :             {
    1145           0 :                 dumpTypeClass(bDump, typeClass, keyName);
    1146           0 :                 fprintf(stdout, "    nFields1 = %d  !=  nFields2 = %d\n", nFields1, nFields2);
    1147             :             }
    1148           0 :             nError++;
    1149             :         }
    1150             : 
    1151             :         sal_uInt16 i;
    1152           0 :         for (i=0; i < nFields1 && i < nFields2; i++)
    1153             :         {
    1154           0 :             nError += checkField(options, keyName, typeClass, bDump, reader1, reader2, i, i, REPORT);
    1155             :         }
    1156           0 :         if ( i < nFields1 && options.forceOutput() )
    1157             :         {
    1158           0 :             dumpTypeClass(bDump, typeClass, keyName);
    1159           0 :             fprintf(stdout, "    Registry1 contains %d more fields\n", nFields1 - i);
    1160             :         }
    1161           0 :         if ( i < nFields2 && options.forceOutput() )
    1162             :         {
    1163           0 :             dumpTypeClass(bDump, typeClass, keyName);
    1164           0 :             fprintf(stdout, "    Registry2 contains %d more fields\n", nFields2 - i);
    1165             :         }
    1166             :     }
    1167             :     else
    1168             :     {
    1169           0 :         nError += checkFieldsWithoutOrder(options, keyName, typeClass, bDump, reader1, reader2);
    1170             :     }
    1171             : 
    1172           0 :     if ( typeClass == RT_TYPE_INTERFACE )
    1173             :     {
    1174           0 :         sal_uInt16 nMethods1 = (sal_uInt16)reader1.getMethodCount();
    1175           0 :         sal_uInt16 nMethods2 = (sal_uInt16)reader2.getMethodCount();
    1176           0 :         if ( nMethods1 != nMethods2 )
    1177             :         {
    1178           0 :             if ( options.forceOutput() )
    1179             :             {
    1180           0 :                 dumpTypeClass(bDump, typeClass, keyName);
    1181           0 :                 fprintf(stdout, "    nMethods1 = %d  !=  nMethods2 = %d\n", nMethods1, nMethods2);
    1182             :             }
    1183           0 :             nError++;
    1184             :         }
    1185             : 
    1186             :         sal_uInt16 i;
    1187           0 :         for (i=0; i < nMethods1 && i < nMethods2; i++)
    1188             :         {
    1189           0 :             nError += checkMethod(options, keyName, typeClass, bDump, reader1, reader2, i);
    1190             :         }
    1191           0 :         if ( i < nMethods1 && options.forceOutput() )
    1192             :         {
    1193           0 :             fprintf(stdout, "    Registry1 contains %d more methods\n", nMethods1 - i);
    1194             :         }
    1195           0 :         if ( i < nMethods2 && options.forceOutput() )
    1196             :         {
    1197           0 :             fprintf(stdout, "    Registry2 contains %d more methods\n", nMethods2 - i);
    1198             :         }
    1199             :     }
    1200           0 :     if ( typeClass == RT_TYPE_SERVICE )
    1201             :     {
    1202           0 :         sal_uInt16 nReference1 = (sal_uInt16)reader1.getReferenceCount();
    1203           0 :         sal_uInt16 nReference2 = (sal_uInt16)reader2.getReferenceCount();
    1204             : 
    1205           0 :         if ( !bCheckNormal )
    1206             :         {
    1207           0 :             sal_uInt16 i=0, j=0;
    1208             : 
    1209           0 :             if ( nReference1 > nReference2 )
    1210             :             {
    1211           0 :                 if ( options.forceOutput() )
    1212             :                 {
    1213           0 :                     dumpTypeClass(bDump, typeClass, keyName);
    1214             :                     fprintf(stdout, "    service1 contains %d more references as service2\n",
    1215           0 :                             nReference1-nReference2);
    1216             :                 }
    1217             :             }
    1218             : 
    1219           0 :             bool bFound = false;
    1220           0 :             ::std::set< sal_uInt16 > moreReferences;
    1221             : 
    1222           0 :             for (i=0; i < nReference1; i++)
    1223             :             {
    1224           0 :                 for (j=0; j < nReference2; j++)
    1225             :                 {
    1226           0 :                     if (!checkReference(options, keyName, typeClass, bDump, reader1, reader2, i, j))
    1227             :                     {
    1228           0 :                         bFound =  true;
    1229           0 :                         moreReferences.insert(j);
    1230           0 :                         break;
    1231             :                     }
    1232             :                 }
    1233           0 :                 if (!bFound)
    1234             :                 {
    1235           0 :                     if (options.forceOutput())
    1236             :                     {
    1237           0 :                         dumpTypeClass(bDump, typeClass, keyName);
    1238             :                         fprintf(stdout,
    1239             :                                 "  incompatible change: Reference %d ('%s') in 'r1' is not longer a reference"
    1240             :                                 " of this service in 'r2'\n",
    1241           0 :                                 i, U2S(shortName(reader1.getReferenceTypeName(i))));
    1242             :                     }
    1243           0 :                     nError++;
    1244             :                 }
    1245             :                 else
    1246             :                 {
    1247           0 :                     bFound = false;
    1248             :                 }
    1249             :             }
    1250             : 
    1251           0 :             if ( !moreReferences.empty() )
    1252             :             {
    1253           0 :                 for (j=0; j < nReference2; j++)
    1254             :                 {
    1255           0 :                     if ( moreReferences.find(j) == moreReferences.end() )
    1256             :                     {
    1257           0 :                         if ( (reader2.getReferenceFlags(j) & RT_ACCESS_OPTIONAL) != RT_ACCESS_OPTIONAL )
    1258             :                         {
    1259           0 :                             if ( options.forceOutput() )
    1260             :                             {
    1261           0 :                                 dumpTypeClass(bDump, typeClass, keyName);
    1262             :                                 fprintf(stdout,
    1263             :                                         "  incompatible change: Reference %d ('%s') of r2 is a new reference"
    1264             :                                         " compared to this service in r1 and is not 'optional'\n",
    1265           0 :                                         j, U2S(shortName(reader2.getReferenceTypeName(j))));
    1266             :                             }
    1267           0 :                             nError++;
    1268             :                         }
    1269             :                     }
    1270             :                 }
    1271           0 :             }
    1272             :         }
    1273             :         else
    1274             :         {
    1275           0 :             if ( nReference1 != nReference2 )
    1276             :             {
    1277           0 :                 if ( options.forceOutput() )
    1278             :                 {
    1279           0 :                     dumpTypeClass(bDump, typeClass, keyName);
    1280           0 :                     fprintf(stdout, "    nReferences1 = %d  !=  nReferences2 = %d\n", nReference1, nReference2);
    1281             :                 }
    1282           0 :                 nError++;
    1283             :             }
    1284             : 
    1285             :             sal_uInt16 i;
    1286           0 :             for (i=0; i < nReference1 && i < nReference2; i++)
    1287             :             {
    1288           0 :                 nError += checkReference(options, keyName, typeClass, bDump, reader1, reader2, i, i);
    1289             :             }
    1290           0 :             if ( i < nReference1 && options.forceOutput() )
    1291             :             {
    1292           0 :                 fprintf(stdout, "    Registry1 contains %d more references\n", nReference1 - i);
    1293             :             }
    1294           0 :             if ( i < nReference2 && options.forceOutput() )
    1295             :             {
    1296           0 :                 fprintf(stdout, "    Registry2 contains %d more references\n", nReference2 - i);
    1297             :             }
    1298             :         }
    1299             :     }
    1300             : 
    1301           0 :     if ( options.fullCheck() && (reader1.getDocumentation() != reader2.getDocumentation()) )
    1302             :     {
    1303           0 :         if ( options.forceOutput() )
    1304             :         {
    1305           0 :             dumpTypeClass(bDump, typeClass, keyName);
    1306             :             fprintf(stdout, "    Doku1 = %s\n    Doku2 = %s\n",
    1307           0 :                     U2S(reader1.getDocumentation()), U2S(reader2.getDocumentation()));
    1308             :         }
    1309           0 :         nError++;
    1310             :     }
    1311           0 :     return nError;
    1312             : }
    1313             : 
    1314           0 : static sal_uInt32 checkValueDifference(
    1315             :     Options_Impl const & options,
    1316             :     RegistryKey& key1, RegValueType valueType1, sal_uInt32 size1,
    1317             :     RegistryKey& key2, RegValueType valueType2, sal_uInt32 size2)
    1318             : {
    1319           0 :     OUString tmpName;
    1320           0 :     sal_uInt32 nError = 0;
    1321             : 
    1322           0 :     if ( valueType1 == valueType2 )
    1323             :     {
    1324           0 :         bool bEqual = true;
    1325           0 :         switch (valueType1)
    1326             :         {
    1327             :         case RG_VALUETYPE_LONGLIST:
    1328             :             {
    1329           0 :                 RegistryValueList<sal_Int32> valueList1;
    1330           0 :                 RegistryValueList<sal_Int32> valueList2;
    1331           0 :                 key1.getLongListValue(tmpName, valueList1);
    1332           0 :                 key2.getLongListValue(tmpName, valueList2);
    1333           0 :                 sal_uInt32 length1 = valueList1.getLength();
    1334           0 :                 sal_uInt32 length2 = valueList1.getLength();
    1335           0 :                 if ( length1 != length2 )
    1336             :                 {
    1337           0 :                     bEqual = false;
    1338           0 :                     break;
    1339             :                 }
    1340           0 :                 for (sal_uInt32 i=0; i<length1; i++)
    1341             :                 {
    1342           0 :                     if ( valueList1.getElement(i) != valueList2.getElement(i) )
    1343             :                     {
    1344           0 :                         bEqual = false;
    1345           0 :                         break;
    1346             :                     }
    1347           0 :                 }
    1348             :             }
    1349           0 :             break;
    1350             :         case RG_VALUETYPE_STRINGLIST:
    1351             :             {
    1352           0 :                 RegistryValueList<sal_Char*> valueList1;
    1353           0 :                 RegistryValueList<sal_Char*> valueList2;
    1354           0 :                 key1.getStringListValue(tmpName, valueList1);
    1355           0 :                 key2.getStringListValue(tmpName, valueList2);
    1356           0 :                 sal_uInt32 length1 = valueList1.getLength();
    1357           0 :                 sal_uInt32 length2 = valueList1.getLength();
    1358           0 :                 if ( length1 != length2 )
    1359             :                 {
    1360           0 :                     bEqual = false;
    1361           0 :                     break;
    1362             :                 }
    1363           0 :                 for (sal_uInt32 i=0; i<length1; i++)
    1364             :                 {
    1365           0 :                     if ( strcmp(valueList1.getElement(i), valueList2.getElement(i)) != 0 )
    1366             :                     {
    1367           0 :                         bEqual = false;
    1368           0 :                         break;
    1369             :                     }
    1370           0 :                 }
    1371             :             }
    1372           0 :             break;
    1373             :         case RG_VALUETYPE_UNICODELIST:
    1374             :             {
    1375           0 :                 RegistryValueList<sal_Unicode*> valueList1;
    1376           0 :                 RegistryValueList<sal_Unicode*> valueList2;
    1377           0 :                 key1.getUnicodeListValue(tmpName, valueList1);
    1378           0 :                 key2.getUnicodeListValue(tmpName, valueList2);
    1379           0 :                 sal_uInt32 length1 = valueList1.getLength();
    1380           0 :                 sal_uInt32 length2 = valueList1.getLength();
    1381           0 :                 if ( length1 != length2 )
    1382             :                 {
    1383           0 :                     bEqual = false;
    1384           0 :                     break;
    1385             :                 }
    1386           0 :                 for (sal_uInt32 i=0; i<length1; i++)
    1387             :                 {
    1388           0 :                     if ( rtl_ustr_compare(valueList1.getElement(i), valueList2.getElement(i)) != 0 )
    1389             :                     {
    1390           0 :                         bEqual = false;
    1391           0 :                         break;
    1392             :                     }
    1393           0 :                 }
    1394             :             }
    1395           0 :             break;
    1396             :         default:
    1397           0 :             break;
    1398             :         }
    1399             : 
    1400           0 :         if ( bEqual)
    1401             :         {
    1402           0 :             std::vector< sal_uInt8 > value1(size1);
    1403           0 :             key1.getValue(tmpName, &value1[0]);
    1404             : 
    1405           0 :             std::vector< sal_uInt8 > value2(size2);
    1406           0 :             key2.getValue(tmpName, &value2[0]);
    1407             : 
    1408           0 :             bEqual = (memcmp(&value1[0], &value2[0], value1.size()) == 0 );
    1409           0 :             if ( !bEqual && valueType1 == RG_VALUETYPE_BINARY && valueType2 == RG_VALUETYPE_BINARY )
    1410             :             {
    1411           0 :                 typereg::Reader reader1(&value1[0], value1.size(), false, TYPEREG_VERSION_1);
    1412           0 :                 typereg::Reader reader2(&value2[0], value2.size(), false, TYPEREG_VERSION_1);
    1413           0 :                 if ( reader1.isValid() && reader2.isValid() )
    1414             :                 {
    1415           0 :                     return checkBlob(options, key1.getName(), reader1, size1, reader2, size2);
    1416           0 :                 }
    1417             :             }
    1418           0 :             if ( bEqual )
    1419             :             {
    1420           0 :                 return 0;
    1421             :             }
    1422             :             else
    1423             :             {
    1424           0 :                 if ( options.forceOutput() )
    1425             :                 {
    1426           0 :                     fprintf(stdout, "Difference: key values of key \"%s\" are different\n", U2S(key1.getName()));
    1427             :                 }
    1428           0 :                 nError++;
    1429           0 :             }
    1430             :         }
    1431             :     }
    1432             : 
    1433           0 :     if ( options.forceOutput() )
    1434             :     {
    1435           0 :         switch (valueType1)
    1436             :         {
    1437             :         case RG_VALUETYPE_NOT_DEFINED:
    1438           0 :             fprintf(stdout, "    Registry 1: key has no value\n");
    1439           0 :             break;
    1440             :         case RG_VALUETYPE_LONG:
    1441             :             {
    1442           0 :                 std::vector< sal_uInt8 > value1(size1);
    1443           0 :                 key1.getValue(tmpName, &value1[0]);
    1444             : 
    1445           0 :                 fprintf(stdout, "    Registry 1: Value: Type = RG_VALUETYPE_LONG\n");
    1446             :                 fprintf(
    1447             :                     stdout, "                       Size = %lu\n",
    1448           0 :                     sal::static_int_cast< unsigned long >(size1));
    1449           0 :                 fprintf(stdout, "                       Data = %p\n", &value1[0]);
    1450             :             }
    1451           0 :             break;
    1452             :         case RG_VALUETYPE_STRING:
    1453             :             {
    1454           0 :                 std::vector< sal_uInt8 > value1(size1);
    1455           0 :                 key1.getValue(tmpName, &value1[0]);
    1456             : 
    1457           0 :                 fprintf(stdout, "    Registry 1: Value: Type = RG_VALUETYPE_STRING\n");
    1458             :                 fprintf(
    1459             :                     stdout, "                       Size = %lu\n",
    1460           0 :                     sal::static_int_cast< unsigned long >(size1));
    1461           0 :                 fprintf(stdout, "                       Data = \"%s\"\n", reinterpret_cast<char const*>(&value1[0]));
    1462             :             }
    1463           0 :             break;
    1464             :         case RG_VALUETYPE_UNICODE:
    1465             :             {
    1466           0 :                 std::vector< sal_uInt8 > value1(size1);
    1467           0 :                 key1.getValue(tmpName, &value1[0]);
    1468             : 
    1469           0 :                 OUString uStrValue(reinterpret_cast<sal_Unicode const*>(&value1[0]));
    1470           0 :                 fprintf(stdout, "    Registry 1: Value: Type = RG_VALUETYPE_UNICODE\n");
    1471             :                 fprintf(
    1472             :                     stdout, "                       Size = %lu\n",
    1473           0 :                     sal::static_int_cast< unsigned long >(size1));
    1474           0 :                 fprintf(stdout, "                       Data = \"%s\"\n", U2S(uStrValue));
    1475             :             }
    1476           0 :             break;
    1477             :         case RG_VALUETYPE_BINARY:
    1478           0 :             fprintf(stdout, "    Registry 1: Value: Type = RG_VALUETYPE_BINARY\n");
    1479           0 :             break;
    1480             :         case RG_VALUETYPE_LONGLIST:
    1481             :             {
    1482           0 :                 RegistryValueList<sal_Int32> valueList;
    1483           0 :                 key1.getLongListValue(tmpName, valueList);
    1484           0 :                 fprintf(stdout, "    Registry 1: Value: Type = RG_VALUETYPE_LONGLIST\n");
    1485             :                 fprintf(
    1486             :                     stdout, "                       Size = %lu\n",
    1487           0 :                     sal::static_int_cast< unsigned long >(size1));
    1488           0 :                 sal_uInt32 length = valueList.getLength();
    1489           0 :                 for (sal_uInt32 i=0; i<length; i++)
    1490             :                 {
    1491             :                     fprintf(
    1492             :                         stdout, "                       Data[%lu] = %ld\n",
    1493             :                         sal::static_int_cast< unsigned long >(i),
    1494           0 :                         sal::static_int_cast< long >(valueList.getElement(i)));
    1495           0 :                 }
    1496             :             }
    1497           0 :             break;
    1498             :         case RG_VALUETYPE_STRINGLIST:
    1499             :             {
    1500           0 :                 RegistryValueList<sal_Char*> valueList;
    1501           0 :                 key1.getStringListValue(tmpName, valueList);
    1502           0 :                 fprintf(stdout, "    Registry 1: Value: Type = RG_VALUETYPE_STRINGLIST\n");
    1503             :                 fprintf(
    1504             :                     stdout, "                       Size = %lu\n",
    1505           0 :                     sal::static_int_cast< unsigned long >(size1));
    1506           0 :                 sal_uInt32 length = valueList.getLength();
    1507           0 :                 for (sal_uInt32 i=0; i<length; i++)
    1508             :                 {
    1509             :                     fprintf(
    1510             :                         stdout, "                       Data[%lu] = \"%s\"\n",
    1511             :                         sal::static_int_cast< unsigned long >(i),
    1512           0 :                         valueList.getElement(i));
    1513           0 :                 }
    1514             :             }
    1515           0 :             break;
    1516             :         case RG_VALUETYPE_UNICODELIST:
    1517             :             {
    1518           0 :                 RegistryValueList<sal_Unicode*> valueList;
    1519           0 :                 key1.getUnicodeListValue(tmpName, valueList);
    1520           0 :                 fprintf(stdout, "    Registry 1: Value: Type = RG_VALUETYPE_UNICODELIST\n");
    1521             :                 fprintf(
    1522             :                     stdout, "                       Size = %lu\n",
    1523           0 :                     sal::static_int_cast< unsigned long >(size1));
    1524           0 :                 sal_uInt32 length = valueList.getLength();
    1525           0 :                 OUString uStrValue;
    1526           0 :                 for (sal_uInt32 i=0; i<length; i++)
    1527             :                 {
    1528           0 :                     uStrValue = OUString(valueList.getElement(i));
    1529             :                     fprintf(
    1530             :                         stdout, "                       Data[%lu] = \"%s\"\n",
    1531           0 :                         sal::static_int_cast< unsigned long >(i), U2S(uStrValue));
    1532           0 :                 }
    1533             :             }
    1534           0 :             break;
    1535             :         }
    1536             : 
    1537           0 :         switch (valueType2)
    1538             :         {
    1539             :         case RG_VALUETYPE_NOT_DEFINED:
    1540           0 :             fprintf(stdout, "    Registry 2: key has no value\n");
    1541           0 :             break;
    1542             :         case RG_VALUETYPE_LONG:
    1543             :             {
    1544           0 :                 std::vector< sal_uInt8 > value2(size2);
    1545           0 :                 key2.getValue(tmpName, &value2[0]);
    1546             : 
    1547           0 :                 fprintf(stdout, "    Registry 2: Value: Type = RG_VALUETYPE_LONG\n");
    1548             :                 fprintf(
    1549             :                     stdout, "                       Size = %lu\n",
    1550           0 :                     sal::static_int_cast< unsigned long >(size2));
    1551           0 :                 fprintf(stdout, "                       Data = %p\n", &value2[0]);
    1552             :             }
    1553           0 :             break;
    1554             :         case RG_VALUETYPE_STRING:
    1555             :             {
    1556           0 :                 std::vector< sal_uInt8 > value2(size2);
    1557           0 :                 key2.getValue(tmpName, &value2[0]);
    1558             : 
    1559           0 :                 fprintf(stdout, "    Registry 2: Value: Type = RG_VALUETYPE_STRING\n");
    1560             :                 fprintf(
    1561             :                     stdout, "                       Size = %lu\n",
    1562           0 :                     sal::static_int_cast< unsigned long >(size2));
    1563           0 :                 fprintf(stdout, "                       Data = \"%s\"\n", reinterpret_cast<char const*>(&value2[0]));
    1564             :             }
    1565           0 :             break;
    1566             :         case RG_VALUETYPE_UNICODE:
    1567             :             {
    1568           0 :                 std::vector< sal_uInt8 > value2(size2);
    1569           0 :                 key2.getValue(tmpName, &value2[0]);
    1570             : 
    1571           0 :                 OUString uStrValue(reinterpret_cast<sal_Unicode const*>(&value2[0]));
    1572           0 :                 fprintf(stdout, "    Registry 2: Value: Type = RG_VALUETYPE_UNICODE\n");
    1573             :                 fprintf(
    1574             :                     stdout, "                       Size = %lu\n",
    1575           0 :                     sal::static_int_cast< unsigned long >(size2));
    1576           0 :                 fprintf(stdout, "                       Data = \"%s\"\n", U2S(uStrValue));
    1577             :             }
    1578           0 :             break;
    1579             :         case RG_VALUETYPE_BINARY:
    1580           0 :             fprintf(stdout, "    Registry 2: Value: Type = RG_VALUETYPE_BINARY\n");
    1581           0 :             break;
    1582             :         case RG_VALUETYPE_LONGLIST:
    1583             :             {
    1584           0 :                 RegistryValueList<sal_Int32> valueList;
    1585           0 :                 key2.getLongListValue(tmpName, valueList);
    1586           0 :                 fprintf(stdout, "    Registry 2: Value: Type = RG_VALUETYPE_LONGLIST\n");
    1587             :                 fprintf(
    1588             :                     stdout, "                       Size = %lu\n",
    1589           0 :                     sal::static_int_cast< unsigned long >(size2));
    1590           0 :                 sal_uInt32 length = valueList.getLength();
    1591           0 :                 for (sal_uInt32 i=0; i<length; i++)
    1592             :                 {
    1593             :                     fprintf(
    1594             :                         stdout, "                       Data[%lu] = %ld\n",
    1595             :                         sal::static_int_cast< unsigned long >(i),
    1596           0 :                         sal::static_int_cast< long >(valueList.getElement(i)));
    1597           0 :                 }
    1598             :             }
    1599           0 :             break;
    1600             :         case RG_VALUETYPE_STRINGLIST:
    1601             :             {
    1602           0 :                 RegistryValueList<sal_Char*> valueList;
    1603           0 :                 key2.getStringListValue(tmpName, valueList);
    1604           0 :                 fprintf(stdout, "    Registry 2: Value: Type = RG_VALUETYPE_STRINGLIST\n");
    1605             :                 fprintf(
    1606             :                     stdout, "                       Size = %lu\n",
    1607           0 :                     sal::static_int_cast< unsigned long >(size2));
    1608           0 :                 sal_uInt32 length = valueList.getLength();
    1609           0 :                 for (sal_uInt32 i=0; i<length; i++)
    1610             :                 {
    1611             :                     fprintf(
    1612             :                         stdout, "                       Data[%lu] = \"%s\"\n",
    1613             :                         sal::static_int_cast< unsigned long >(i),
    1614           0 :                         valueList.getElement(i));
    1615           0 :                 }
    1616             :             }
    1617           0 :             break;
    1618             :         case RG_VALUETYPE_UNICODELIST:
    1619             :             {
    1620           0 :                 RegistryValueList<sal_Unicode*> valueList;
    1621           0 :                 key2.getUnicodeListValue(tmpName, valueList);
    1622           0 :                 fprintf(stdout, "    Registry 2: Value: Type = RG_VALUETYPE_UNICODELIST\n");
    1623             :                 fprintf(
    1624             :                     stdout, "                       Size = %lu\n",
    1625           0 :                     sal::static_int_cast< unsigned long >(size2));
    1626           0 :                 sal_uInt32 length = valueList.getLength();
    1627           0 :                 OUString uStrValue;
    1628           0 :                 for (sal_uInt32 i=0; i<length; i++)
    1629             :                 {
    1630           0 :                     uStrValue = OUString(valueList.getElement(i));
    1631             :                     fprintf(
    1632             :                         stdout, "                       Data[%lu] = \"%s\"\n",
    1633           0 :                         sal::static_int_cast< unsigned long >(i), U2S(uStrValue));
    1634           0 :                 }
    1635             :             }
    1636           0 :             break;
    1637             :         }
    1638             :     }
    1639           0 :     return nError;
    1640             : }
    1641             : 
    1642           0 : static bool hasPublishedChildren(Options_Impl const & options, RegistryKey & key)
    1643             : {
    1644           0 :     RegistryKeyNames subKeyNames;
    1645           0 :     key.getKeyNames(OUString(), subKeyNames);
    1646           0 :     for (sal_uInt32 i = 0; i < subKeyNames.getLength(); ++i)
    1647             :     {
    1648           0 :         OUString keyName(subKeyNames.getElement(i));
    1649           0 :         if (!options.matchedWithExcludeKey(keyName))
    1650             :         {
    1651           0 :             keyName = keyName.copy(keyName.lastIndexOf('/') + 1);
    1652           0 :             RegistryKey subKey;
    1653           0 :             if (!key.openKey(keyName, subKey))
    1654             :             {
    1655           0 :                 if (options.forceOutput())
    1656             :                 {
    1657             :                     fprintf(
    1658             :                         stdout,
    1659             :                         ("WARNING: could not open key \"%s\" in registry"
    1660             :                          " \"%s\"\n"),
    1661             :                         U2S(subKeyNames.getElement(i)),
    1662           0 :                         options.getRegName1().c_str());
    1663             :                 }
    1664             :             }
    1665           0 :             if (subKey.isValid())
    1666             :             {
    1667             :                 RegValueType type;
    1668             :                 sal_uInt32 size;
    1669           0 :                 if (subKey.getValueInfo(OUString(), &type, &size) != REG_NO_ERROR)
    1670             :                 {
    1671           0 :                     if (options.forceOutput())
    1672             :                     {
    1673             :                         fprintf(
    1674             :                             stdout,
    1675             :                             ("WARNING: could not read key \"%s\" in registry"
    1676             :                              " \"%s\"\n"),
    1677             :                             U2S(subKeyNames.getElement(i)),
    1678           0 :                             options.getRegName1().c_str());
    1679             :                     }
    1680             :                 }
    1681           0 :                 else if (type == RG_VALUETYPE_BINARY)
    1682             :                 {
    1683           0 :                     bool published = false;
    1684           0 :                     std::vector< sal_uInt8 > value(size);
    1685           0 :                     if (subKey.getValue(OUString(), &value[0]) != REG_NO_ERROR)
    1686             :                     {
    1687           0 :                         if (options.forceOutput())
    1688             :                         {
    1689             :                             fprintf(
    1690             :                                 stdout,
    1691             :                                 ("WARNING: could not read key \"%s\" in"
    1692             :                                  " registry \"%s\"\n"),
    1693             :                                 U2S(subKeyNames.getElement(i)),
    1694           0 :                                 options.getRegName1().c_str());
    1695             :                         }
    1696             :                     }
    1697             :                     else
    1698             :                     {
    1699           0 :                         published = typereg::Reader(&value[0], value.size(), false, TYPEREG_VERSION_1).isPublished();
    1700             :                     }
    1701           0 :                     if (published)
    1702             :                     {
    1703           0 :                         return true;
    1704           0 :                     }
    1705             :                 }
    1706           0 :             }
    1707             :         }
    1708           0 :     }
    1709           0 :     return false;
    1710             : }
    1711             : 
    1712           0 : static sal_uInt32 checkDifferences(
    1713             :     Options_Impl const & options,
    1714             :     RegistryKey& key, StringSet& keys,
    1715             :     RegistryKeyNames& subKeyNames1,
    1716             :     RegistryKeyNames& subKeyNames2)
    1717             : {
    1718           0 :     sal_uInt32 nError = 0;
    1719           0 :     sal_uInt32 length1 = subKeyNames1.getLength();
    1720           0 :     sal_uInt32 length2 = subKeyNames2.getLength();
    1721             :     sal_uInt32 i,j;
    1722             : 
    1723           0 :     for (i=0; i<length1; i++)
    1724             :     {
    1725           0 :         bool bFound = false;
    1726           0 :         for (j=0; j<length2; j++)
    1727             :         {
    1728           0 :             if ( subKeyNames1.getElement(i) == subKeyNames2.getElement(j) )
    1729             :             {
    1730           0 :                 bFound = true;
    1731           0 :                 keys.insert(subKeyNames1.getElement(i));
    1732           0 :                 break;
    1733             :             }
    1734             :         }
    1735           0 :         if ( !bFound )
    1736             :         {
    1737           0 :             if ( options.fullCheck() )
    1738             :             {
    1739           0 :                 if ( options.forceOutput() )
    1740             :                 {
    1741             :                     fprintf(stdout, "EXISTENCE: key \"%s\" exists only in registry \"%s\"\n",
    1742           0 :                             U2S(subKeyNames1.getElement(i)), options.getRegName1().c_str());
    1743             :                 }
    1744           0 :                 nError++;
    1745             :             }
    1746             :             else
    1747             :             {
    1748           0 :                 OUString keyName(subKeyNames1.getElement(i));
    1749           0 :                 if (!options.matchedWithExcludeKey(keyName))
    1750             :                 {
    1751           0 :                     keyName = keyName.copy(keyName.lastIndexOf('/') + 1);
    1752           0 :                     RegistryKey subKey;
    1753           0 :                     if (key.openKey(keyName, subKey))
    1754             :                     {
    1755           0 :                         if (options.forceOutput())
    1756             :                         {
    1757             :                             fprintf(
    1758             :                                 stdout,
    1759             :                                 ("ERROR: could not open key \"%s\" in registry"
    1760             :                                  " \"%s\"\n"),
    1761             :                                 U2S(subKeyNames1.getElement(i)),
    1762           0 :                                 options.getRegName1().c_str());
    1763             :                         }
    1764           0 :                         ++nError;
    1765             :                     }
    1766           0 :                     if (subKey.isValid())
    1767             :                     {
    1768             :                         RegValueType type;
    1769             :                         sal_uInt32 size;
    1770           0 :                         if (subKey.getValueInfo(OUString(), &type, &size) != REG_NO_ERROR)
    1771             :                         {
    1772           0 :                             if (options.forceOutput())
    1773             :                             {
    1774             :                                 fprintf(
    1775             :                                     stdout,
    1776             :                                     ("ERROR: could not read key \"%s\" in"
    1777             :                                      " registry \"%s\"\n"),
    1778             :                                     U2S(subKeyNames1.getElement(i)),
    1779           0 :                                     options.getRegName1().c_str());
    1780             :                             }
    1781           0 :                             ++nError;
    1782             :                         }
    1783           0 :                         else if (type == RG_VALUETYPE_BINARY)
    1784             :                         {
    1785           0 :                             std::vector< sal_uInt8 > value(size);
    1786           0 :                             if (subKey.getValue(OUString(), &value[0]) != REG_NO_ERROR)
    1787             :                             {
    1788           0 :                                 if (options.forceOutput())
    1789             :                                 {
    1790             :                                     fprintf(
    1791             :                                         stdout,
    1792             :                                         ("ERROR: could not read key \"%s\" in"
    1793             :                                          " registry \"%s\"\n"),
    1794             :                                         U2S(subKeyNames1.getElement(i)),
    1795           0 :                                         options.getRegName1().c_str());
    1796             :                                 }
    1797           0 :                                 ++nError;
    1798             :                             }
    1799             :                             else
    1800             :                             {
    1801           0 :                                 typereg::Reader reader(&value[0], value.size(), false, TYPEREG_VERSION_1);
    1802           0 :                                 if (reader.getTypeClass() == RT_TYPE_MODULE)
    1803             :                                 {
    1804           0 :                                     if (options.checkUnpublished() || hasPublishedChildren(options, subKey))
    1805             :                                     {
    1806           0 :                                         if (options.forceOutput())
    1807             :                                         {
    1808             :                                             fprintf(
    1809             :                                                 stdout,
    1810             :                                                 ("EXISTENCE: module \"%s\""
    1811             :                                                  " %sexists only in registry"
    1812             :                                                  " 1\n"),
    1813             :                                                 U2S(subKeyNames1.getElement(i)),
    1814           0 :                                                 (options.checkUnpublished()
    1815             :                                                  ? ""
    1816           0 :                                                  : "with published children "));
    1817             :                                         }
    1818           0 :                                         ++nError;
    1819             :                                     }
    1820             :                                 }
    1821           0 :                                 else if (options.checkUnpublished() || reader.isPublished())
    1822             :                                 {
    1823           0 :                                     if (options.forceOutput())
    1824             :                                     {
    1825             :                                         fprintf(
    1826             :                                             stdout,
    1827             :                                             ("EXISTENCE: %spublished key \"%s\""
    1828             :                                              " exists only in registry 1\n"),
    1829           0 :                                             reader.isPublished() ? "" : "un",
    1830           0 :                                             U2S(subKeyNames1.getElement(i)));
    1831             :                                     }
    1832           0 :                                     ++nError;
    1833           0 :                                 }
    1834           0 :                             }
    1835             :                         }
    1836           0 :                     }
    1837           0 :                 }
    1838             :             }
    1839             :         }
    1840             :     }
    1841             : 
    1842           0 :     for (i=0; i<length2; i++)
    1843             :     {
    1844           0 :         bool bFound = false;
    1845           0 :         for (j=0; j<length1; j++)
    1846             :         {
    1847           0 :             if ( subKeyNames2.getElement(i) == subKeyNames1.getElement(j) )
    1848             :             {
    1849           0 :                 bFound = true;
    1850           0 :                 keys.insert(subKeyNames2.getElement(i));
    1851           0 :                 break;
    1852             :             }
    1853             :         }
    1854           0 :         if ( !bFound && options.fullCheck() )
    1855             :         {
    1856           0 :             if ( options.forceOutput() )
    1857             :             {
    1858             :                 fprintf(stdout, "EXISTENCE: key \"%s\" exists only in registry \"%s\"\n",
    1859           0 :                         U2S(subKeyNames2.getElement(i)), options.getRegName2().c_str());
    1860             :             }
    1861           0 :             nError++;
    1862             :         }
    1863             :     }
    1864           0 :     return nError;
    1865             : }
    1866             : 
    1867           0 : static sal_uInt32 compareKeys(
    1868             :     Options_Impl const & options,
    1869             :     RegistryKey& key1,
    1870             :     RegistryKey& key2)
    1871             : {
    1872           0 :     sal_uInt32 nError = 0;
    1873             : 
    1874           0 :     RegValueType valueType1 = RG_VALUETYPE_NOT_DEFINED;
    1875           0 :     RegValueType valueType2 = RG_VALUETYPE_NOT_DEFINED;
    1876           0 :     sal_uInt32 size1 = 0;
    1877           0 :     sal_uInt32 size2 = 0;
    1878             : 
    1879           0 :     OUString tmpName;
    1880           0 :     RegError e1 = key1.getValueInfo(tmpName, &valueType1, &size1);
    1881           0 :     RegError e2 = key2.getValueInfo(tmpName, &valueType2, &size2);
    1882           0 :     if ( (e1 == e2) && (e1 != REG_VALUE_NOT_EXISTS) && (e1 != REG_INVALID_VALUE) )
    1883             :     {
    1884           0 :         nError += checkValueDifference(options, key1, valueType1, size1, key2, valueType2, size2);
    1885             :     }
    1886             :     else
    1887             :     {
    1888           0 :         if ( (e1 != REG_INVALID_VALUE) || (e2 != REG_INVALID_VALUE) )
    1889             :         {
    1890           0 :             if ( options.forceOutput() )
    1891             :             {
    1892           0 :                 fprintf(stdout, "VALUES: key values of key \"%s\" are different\n", U2S(key1.getName()));
    1893             :             }
    1894           0 :             nError++;
    1895             :         }
    1896             :     }
    1897             : 
    1898           0 :     RegistryKeyNames subKeyNames1;
    1899           0 :     RegistryKeyNames subKeyNames2;
    1900             : 
    1901           0 :     key1.getKeyNames(tmpName, subKeyNames1);
    1902           0 :     key2.getKeyNames(tmpName, subKeyNames2);
    1903             : 
    1904           0 :     StringSet keys;
    1905           0 :     nError += checkDifferences(options, key1, keys, subKeyNames1, subKeyNames2);
    1906             : 
    1907           0 :     StringSet::iterator iter = keys.begin();
    1908           0 :     StringSet::iterator end = keys.end();
    1909             : 
    1910           0 :     while ( iter !=  end )
    1911             :     {
    1912           0 :         OUString keyName(*iter);
    1913           0 :         if ( options.matchedWithExcludeKey(keyName) )
    1914             :         {
    1915           0 :             ++iter;
    1916           0 :             continue;
    1917             :         }
    1918             : 
    1919           0 :         sal_Int32 nPos = keyName.lastIndexOf( '/' );
    1920           0 :         keyName = keyName.copy( nPos != -1 ? nPos+1 : 0 );
    1921             : 
    1922           0 :         RegistryKey subKey1;
    1923           0 :         if ( key1.openKey(keyName, subKey1) )
    1924             :         {
    1925           0 :             if ( options.forceOutput() )
    1926             :             {
    1927             :                 fprintf(stdout, "ERROR: could not open key \"%s\" in registry \"%s\"\n",
    1928           0 :                         U2S(*iter), options.getRegName1().c_str());
    1929             :             }
    1930           0 :             nError++;
    1931             :         }
    1932             : 
    1933           0 :         RegistryKey subKey2;
    1934           0 :         if ( key2.openKey(keyName, subKey2) )
    1935             :         {
    1936           0 :             if ( options.forceOutput() )
    1937             :             {
    1938             :                 fprintf(stdout, "ERROR: could not open key \"%s\" in registry \"%s\"\n",
    1939           0 :                         U2S(*iter), options.getRegName2().c_str());
    1940             :             }
    1941           0 :             nError++;
    1942             :         }
    1943             : 
    1944           0 :         if ( subKey1.isValid() && subKey2.isValid() )
    1945             :         {
    1946           0 :             nError += compareKeys(options, subKey1, subKey2);
    1947             :         }
    1948           0 :         ++iter;
    1949           0 :     }
    1950             : 
    1951           0 :     return nError;
    1952             : }
    1953             : 
    1954             : #if (defined UNX) || defined __MINGW32__
    1955           0 : int main( int argc, char * argv[] )
    1956             : #else
    1957             : int _cdecl main( int argc, char * argv[] )
    1958             : #endif
    1959             : {
    1960           0 :     std::vector< std::string > args;
    1961             : 
    1962           0 :     Options_Impl options(argv[0]);
    1963           0 :     for (int i = 1; i < argc; i++)
    1964             :     {
    1965           0 :         if (!Options::checkArgument(args, argv[i], strlen(argv[i])))
    1966             :         {
    1967             :             // failure.
    1968           0 :             options.printUsage();
    1969           0 :             return (1);
    1970             :         }
    1971             :     }
    1972           0 :     if (!options.initOptions(args))
    1973             :     {
    1974           0 :         return (1);
    1975             :     }
    1976             : 
    1977           0 :     OUString regName1( convertToFileUrl(options.getRegName1().c_str(), options.getRegName1().size()) );
    1978           0 :     OUString regName2( convertToFileUrl(options.getRegName2().c_str(), options.getRegName2().size()) );
    1979             : 
    1980           0 :     Registry reg1, reg2;
    1981           0 :     if ( reg1.open(regName1, REG_READONLY) )
    1982             :     {
    1983             :         fprintf(stdout, "%s: open registry \"%s\" failed\n",
    1984           0 :                 options.getProgramName().c_str(), options.getRegName1().c_str());
    1985           0 :         return (2);
    1986             :     }
    1987           0 :     if ( reg2.open(regName2, REG_READONLY) )
    1988             :     {
    1989             :         fprintf(stdout, "%s: open registry \"%s\" failed\n",
    1990           0 :                 options.getProgramName().c_str(), options.getRegName2().c_str());
    1991           0 :         return (3);
    1992             :     }
    1993             : 
    1994           0 :     RegistryKey key1, key2;
    1995           0 :     if ( reg1.openRootKey(key1) )
    1996             :     {
    1997             :         fprintf(stdout, "%s: open root key of registry \"%s\" failed\n",
    1998           0 :                 options.getProgramName().c_str(), options.getRegName1().c_str());
    1999           0 :         return (4);
    2000             :     }
    2001           0 :     if ( reg2.openRootKey(key2) )
    2002             :     {
    2003             :         fprintf(stdout, "%s: open root key of registry \"%s\" failed\n",
    2004           0 :                 options.getProgramName().c_str(), options.getRegName2().c_str());
    2005           0 :         return (5);
    2006             :     }
    2007             : 
    2008           0 :     if ( options.isStartKeyValid() )
    2009             :     {
    2010           0 :         if ( options.matchedWithExcludeKey( options.getStartKey() ) )
    2011             :         {
    2012             :             fprintf(stdout, "%s: start key is equal to one of the exclude keys\n",
    2013           0 :                     options.getProgramName().c_str());
    2014           0 :             return (6);
    2015             :         }
    2016           0 :         RegistryKey sk1, sk2;
    2017           0 :         if ( key1.openKey(options.getStartKey(), sk1) )
    2018             :         {
    2019             :             fprintf(stdout, "%s: open start key of registry \"%s\" failed\n",
    2020           0 :                     options.getProgramName().c_str(), options.getRegName1().c_str());
    2021           0 :             return (7);
    2022             :         }
    2023           0 :         if ( key2.openKey(options.getStartKey(), sk2) )
    2024             :         {
    2025             :             fprintf(stdout, "%s: open start key of registry \"%s\" failed\n",
    2026           0 :                     options.getProgramName().c_str(), options.getRegName2().c_str());
    2027           0 :             return (8);
    2028             :         }
    2029             : 
    2030           0 :         key1 = sk1;
    2031           0 :         key2 = sk2;
    2032             :     }
    2033             : 
    2034           0 :     sal_uInt32 nError = compareKeys(options, key1, key2);
    2035           0 :     if ( nError )
    2036             :     {
    2037           0 :         if ( options.unoTypeCheck() )
    2038             :         {
    2039             :             fprintf(stdout, "%s: registries are incompatible: %lu differences!\n",
    2040           0 :                     options.getProgramName().c_str(),
    2041           0 :                     sal::static_int_cast< unsigned long >(nError));
    2042             :         }
    2043             :         else
    2044             :         {
    2045             :             fprintf(stdout, "%s: registries contain %lu differences!\n",
    2046           0 :                     options.getProgramName().c_str(),
    2047           0 :                     sal::static_int_cast< unsigned long >(nError));
    2048             :         }
    2049             :     }
    2050             : 
    2051           0 :     key1.releaseKey();
    2052           0 :     key2.releaseKey();
    2053           0 :     if ( reg1.close() )
    2054             :     {
    2055             :         fprintf(stdout, "%s: closing registry \"%s\" failed\n",
    2056           0 :                 options.getProgramName().c_str(), options.getRegName1().c_str());
    2057           0 :         return (9);
    2058             :     }
    2059           0 :     if ( reg2.close() )
    2060             :     {
    2061             :         fprintf(stdout, "%s: closing registry \"%s\" failed\n",
    2062           0 :                 options.getProgramName().c_str(), options.getRegName2().c_str());
    2063           0 :         return (10);
    2064             :     }
    2065             : 
    2066           0 :     return ((nError > 0) ? 11 : 0);
    2067             : }
    2068             : 
    2069             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10