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