1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "registry/registry.hxx"
22 #include "registry/reflread.hxx"
23 #include "fileurl.hxx"
24 #include "options.hxx"
26 #include "rtl/ustring.hxx"
27 #include "osl/diagnose.h"
36 using namespace registry::tools
;
39 OUStringToOString(s, RTL_TEXTENCODING_UTF8).getStr()
41 OStringToOUString(s, RTL_TEXTENCODING_UTF8)
43 class Options_Impl
: public Options
46 explicit Options_Impl(char const * program
)
47 : Options (program
), m_bForceOutput(false)
50 std::string
const & getIndexReg() const
51 { return m_indexRegName
; }
52 std::string
const & getTypeReg() const
53 { return m_typeRegName
; }
55 { return (!m_base
.isEmpty()); }
56 const OString
& getBase() const
58 bool forceOutput() const
59 { return m_bForceOutput
; }
62 virtual void printUsage_Impl() const;
63 virtual bool initOptions_Impl (std::vector
< std::string
> & rArgs
);
65 std::string m_indexRegName
;
66 std::string m_typeRegName
;
72 void Options_Impl::printUsage_Impl() const
74 std::string
const & rProgName
= getProgramName();
76 "Usage: %s -r<filename> -o<filename> [-options] | @<filename>\n", rProgName
.c_str()
79 " -o<filename> = filename specifies the name of the new singleton index registry.\n"
80 " -r<filename> = filename specifies the name of the type registry.\n"
81 " @<filename> = filename specifies a command file.\n"
83 " -b<name> = name specifies the name of a start key. The types will be searched\n"
84 " under this key in the type registry.\n"
85 " -f = force the output of all found singletons.\n"
86 " -h|-? = print this help message and exit.\n"
89 "\n%s Version 1.0\n\n", rProgName
.c_str()
94 bool Options_Impl::initOptions_Impl(std::vector
< std::string
> & rArgs
)
96 std::vector
< std::string
>::const_iterator first
= rArgs
.begin(), last
= rArgs
.end();
97 for (; first
!= last
; ++first
)
99 std::string
option (*first
);
100 if ((*first
)[0] != '-')
102 return badOption("invalid", option
.c_str());
109 if (!((++first
!= last
) && ((*first
)[0] != '-')))
111 return badOption("invalid", option
.c_str());
113 m_typeRegName
= *first
;
119 if (!((++first
!= last
) && ((*first
)[0] != '-')))
121 return badOption("invalid", option
.c_str());
123 m_indexRegName
= (*first
);
129 if (!((++first
!= last
) && ((*first
)[0] != '-')))
131 return badOption("invalid", option
.c_str());
133 m_base
= OString((*first
).c_str(), (*first
).size());
139 if ((*first
).size() > 2)
141 return badOption("invalid", option
.c_str());
143 m_bForceOutput
= sal_True
;
149 if ((*first
).size() > 2)
151 return badOption("invalid", option
.c_str());
154 // break; // unreachable
157 return badOption("unknown", option
.c_str());
158 // break; // unreachable
164 static sal_Bool
checkSingletons(Options_Impl
const & options
, RegistryKey
& singletonKey
, RegistryKey
& typeKey
)
166 RegValueType valueType
= RG_VALUETYPE_NOT_DEFINED
;
169 sal_Bool bRet
= sal_False
;
171 RegError e
= typeKey
.getValueInfo(tmpName
, &valueType
, &size
);
172 if ((e
!= REG_VALUE_NOT_EXISTS
) && (e
!= REG_INVALID_VALUE
) && (valueType
== RG_VALUETYPE_BINARY
))
174 std::vector
< sal_uInt8
> value(size
);
175 typeKey
.getValue(tmpName
, &value
[0]); // @@@ broken api: write to buffer w/o buffer size.
177 RegistryTypeReader
reader(&value
[0], value
.size(), sal_False
);
178 if ( reader
.isValid() && reader
.getTypeClass() == RT_TYPE_SINGLETON
)
180 RegistryKey entryKey
;
181 OUString singletonName
= reader
.getTypeName().replace('/', '.');
182 if ( singletonKey
.createKey(singletonName
, entryKey
) )
184 fprintf(stderr
, "%s: could not create SINGLETONS entry for \"%s\"\n",
185 options
.getProgramName().c_str(), U2S( singletonName
));
190 OUString value2
= reader
.getSuperTypeName();
192 if ( entryKey
.setValue(tmpName
, RG_VALUETYPE_UNICODE
,
193 (RegValue
)value2
.getStr(), sizeof(sal_Unicode
)* (value2
.getLength()+1)) )
195 fprintf(stderr
, "%s: could not create data entry for singleton \"%s\"\n",
196 options
.getProgramName().c_str(), U2S( singletonName
));
199 if ( options
.forceOutput() )
201 fprintf(stderr
, "%s: create SINGLETON entry for \"%s\" -> \"%s\"\n",
202 options
.getProgramName().c_str(), U2S( singletonName
), U2S(value2
));
208 RegistryKeyArray subKeys
;
209 typeKey
.openSubKeys(tmpName
, subKeys
);
211 sal_uInt32 length
= subKeys
.getLength();
212 for (sal_uInt32 i
= 0; i
< length
; i
++)
214 RegistryKey elementKey
= subKeys
.getElement(i
);
215 if ( checkSingletons(options
, singletonKey
, elementKey
) )
223 #if (defined UNX) || (defined __MINGW32__)
224 int main( int argc
, char * argv
[] )
226 int _cdecl
main( int argc
, char * argv
[] )
229 std::vector
< std::string
> args
;
230 for (int i
= 1; i
< argc
; i
++)
232 int result
= Options::checkArgument(args
, argv
[i
], strlen(argv
[i
]));
240 Options_Impl
options(argv
[0]);
241 if (!options
.initOptions(args
))
243 options
.printUsage();
247 OUString
indexRegName( convertToFileUrl(options
.getIndexReg().c_str(), options
.getIndexReg().size()) );
249 if ( indexReg
.open(indexRegName
, REG_READWRITE
) )
251 if ( indexReg
.create(indexRegName
) )
253 fprintf(stderr
, "%s: open registry \"%s\" failed\n",
254 options
.getProgramName().c_str(), options
.getIndexReg().c_str());
259 OUString
typeRegName( convertToFileUrl(options
.getTypeReg().c_str(), options
.getTypeReg().size()) );
261 if ( typeReg
.open(typeRegName
, REG_READONLY
) )
263 fprintf(stderr
, "%s: open registry \"%s\" failed\n",
264 options
.getProgramName().c_str(), options
.getTypeReg().c_str());
268 RegistryKey indexRoot
;
269 if ( indexReg
.openRootKey(indexRoot
) )
271 fprintf(stderr
, "%s: open root key of registry \"%s\" failed\n",
272 options
.getProgramName().c_str(), options
.getIndexReg().c_str());
276 RegistryKey typeRoot
;
277 if ( typeReg
.openRootKey(typeRoot
) )
279 fprintf(stderr
, "%s: open root key of registry \"%s\" failed\n",
280 options
.getProgramName().c_str(), options
.getTypeReg().c_str());
285 if ( options
.hasBase() )
287 if ( typeRoot
.openKey(S2U(options
.getBase()), typeKey
) )
289 fprintf(stderr
, "%s: open base key of registry \"%s\" failed\n",
290 options
.getProgramName().c_str(), options
.getTypeReg().c_str());
299 RegistryKey singletonKey
;
300 if ( indexRoot
.createKey(OUString("SINGLETONS"), singletonKey
) )
302 fprintf(stderr
, "%s: open/create SINGLETONS key of registry \"%s\" failed\n",
303 options
.getProgramName().c_str(), options
.getIndexReg().c_str());
307 sal_Bool bSingletonsExist
= checkSingletons(options
, singletonKey
, typeKey
);
309 indexRoot
.releaseKey();
310 typeRoot
.releaseKey();
311 typeKey
.releaseKey();
312 singletonKey
.releaseKey();
313 if ( indexReg
.close() )
315 fprintf(stderr
, "%s: closing registry \"%s\" failed\n",
316 options
.getProgramName().c_str(), options
.getIndexReg().c_str());
319 if ( !bSingletonsExist
)
321 if ( indexReg
.destroy(OUString()) )
323 fprintf(stderr
, "%s: destroy registry \"%s\" failed\n",
324 options
.getProgramName().c_str(), options
.getIndexReg().c_str());
328 if ( typeReg
.close() )
330 fprintf(stderr
, "%s: closing registry \"%s\" failed\n",
331 options
.getProgramName().c_str(), options
.getTypeReg().c_str());
336 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */