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