merge the formfield patch from ooo-build
[ooovba.git] / cpputools / source / regcomplazy / regcomplazy.cxx
blob6c6940ee97fc9617c4b06655bf1427ae31f9452e
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: regcomplazy.cxx,v $
10 * $Revision: 1.7 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include <stdio.h>
33 #include "sal/main.h"
34 #include <osl/diagnose.h>
35 #include <osl/thread.h>
36 #include <osl/file.hxx>
37 #include <rtl/strbuf.hxx>
38 #include <rtl/ustrbuf.hxx>
40 #include <vector>
42 #include <registry/registry.hxx>
45 #define OUSTR(x) ::rtl::OUString::createFromAscii( x )
46 #define OSToOUS(x) ::rtl::OStringToOUString(x, osl_getThreadTextEncoding())
47 #define OUSToOS(x) ::rtl::OUStringToOString(x, osl_getThreadTextEncoding())
48 using namespace ::rtl;
50 typedef ::std::vector< ::rtl::OString > OSVector;
52 typedef ::std::pair< ::rtl::OString, OSVector > DataPair;
54 typedef ::std::vector< DataPair > DataVector;
56 struct CompDescriptor {
57 OString sImplementationName;
58 OString sComponentName;
59 OString sLoaderName;
60 OSVector vSupportedServices;
61 DataVector vData;
64 typedef ::std::vector< CompDescriptor > CDescrVector;
66 static void print_options() SAL_THROW( () )
68 printf(
69 "\nusage: regcomplazy [-v]registry_file cmp_descr_file ...\n\n"
70 "Register a cmponent using a comp description file.\n"
71 "Option -v prints verbose output on stdout.\n" );
74 static bool checkImplValue(RegistryValueList<sal_Char*>* pValueList, OString sImplName) {
75 for (sal_uInt32 i=0; i < pValueList->getLength(); i++) {
76 if (sImplName.equals(pValueList->getElement(i)))
77 return true;
80 return false;
83 //==================================================================================================
84 SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv)
86 if (argc < 3)
88 print_options();
89 return 1;
92 bool bVerbose = false;
93 int nPos = 1;
94 if ('-' == argv[ nPos ][ 0 ] && 'v' == argv[ nPos ][ 1 ])
96 if ('\0' != argv[ nPos ][ 2 ])
98 print_options();
99 return 1;
101 bVerbose = true;
102 ++nPos;
105 OUString sys_path( OUSTR( argv[ nPos ] ) );
106 OUString reg_url;
107 oslFileError rc = osl_getFileURLFromSystemPath( sys_path.pData, &reg_url.pData );
108 if (osl_File_E_None != rc)
110 if (bVerbose)
111 fprintf( stderr, "\nERROR: cannot make file url out of %s\n", argv[nPos]);
112 return 1;
115 FILE* fDescr = fopen(argv[ ++nPos ], "r");
116 OStringBuffer sBuffer(512);
118 if ( fDescr) {
119 size_t totalSize = 0;
120 size_t readSize = 0;
121 char pBuffer[513];
123 while ( !feof(fDescr) )
125 if ( (readSize = fread(pBuffer, 1, 512, fDescr)) > 0
126 && !ferror(fDescr) ) {
127 totalSize += readSize;
128 if (totalSize >= 512)
129 sBuffer.ensureCapacity(totalSize * 2);
131 sBuffer.append(pBuffer, readSize);
134 fclose(fDescr);
135 fDescr = 0; // just to be sure noone tries to use the file ever after
138 OString sDescr = sBuffer.makeStringAndClear();
139 sal_Int32 nTokenIndex = 0;
141 CDescrVector vDescr;
142 CompDescriptor descr;
143 bool bFirst = true;
145 do {
146 OString sTmp = sDescr.getToken(0, '\x0A', nTokenIndex);
147 OString sToken(sTmp);
148 if (sTmp.pData->buffer[sTmp.getLength()-1] == '\x0D')
149 sToken = sTmp.copy(0, sTmp.getLength()-1);
151 if (sToken.indexOf("[Data]") >= 0) {
152 do {
153 OString sTmp2 = sDescr.getToken(0, '\x0A', nTokenIndex);
154 OString sToken2(sTmp2);
155 if (sTmp2.pData->buffer[sTmp2.getLength()-1] == '\x0D')
156 sToken2 = sTmp2.copy(0, sTmp2.getLength()-1);
158 if ((sToken2.getLength() > 0) && (sToken2.pData->buffer[0] != '[')) {
159 OString dataKey(sToken2.copy(0, sToken2.indexOf('=')));
160 OString sValues(sToken2.copy(sToken2.indexOf('=')+1));
161 sal_Int32 nVIndex = 0;
162 OSVector vValues;
163 do {
164 OString sValue = sValues.getToken(0, ';', nVIndex);
165 vValues.push_back(sValue);
166 } while (nVIndex >= 0 );
167 descr.vData.push_back(DataPair(dataKey, vValues));
168 } else
169 break;
170 } while (nTokenIndex >= 0 );
172 if ( sToken.indexOf("[ComponentDescriptor]") >= 0) {
173 if (bFirst)
174 bFirst = false;
175 else
176 vDescr.push_back(descr);
178 descr = CompDescriptor();
180 else if ( sToken.indexOf("ImplementationName=") >= 0) {
181 descr.sImplementationName = sToken.copy(19);
183 else if ( sToken.indexOf("ComponentName=") >= 0) {
184 descr.sComponentName = sToken.copy(14);
186 else if ( sToken.indexOf("LoaderName=") >= 0) {
187 descr.sLoaderName = sToken.copy(11);
189 else if ( (sToken.indexOf("[SupportedServices]") < 0) &&
190 (sToken.getLength() > 0) &&
191 (sToken.pData->buffer[0] != '[') ) {
192 descr.vSupportedServices.push_back(sToken);
194 } while (nTokenIndex >= 0 );
195 // insert the last descriptor
196 vDescr.push_back(descr);
198 Registry *pReg = new Registry;
200 RegistryKey rootKey, key, subKey, serviceKey;
202 if (pReg->open(reg_url, REG_READWRITE))
204 if (pReg->create(reg_url))
206 if (bVerbose)
207 fprintf(stderr, "ERROR: open registry \"%s\" failed\n", argv[1]);
208 return 1;
211 if (pReg->openRootKey(rootKey)) {
212 if (bVerbose)
213 fprintf(stderr, "ERROR: open root key failed\n");
214 return 1;
217 CDescrVector::const_iterator comp_iter = vDescr.begin();
218 do {
219 OString sImplName = (*comp_iter).sImplementationName;
220 OUStringBuffer sbImpl;
221 sbImpl.appendAscii("/IMPLEMENTATIONS/");
222 sbImpl.append(OSToOUS(sImplName));
223 OUString sImplKeyName = sbImpl.makeStringAndClear();
225 if (rootKey.openKey(sImplKeyName, key) == REG_NO_ERROR) {
226 if (bVerbose) {
227 fprintf(stderr, "WARNING: implementation entry for \"%s\" already exists, existing entries are overwritten\n", sImplName.getStr());
229 } else {
230 if (rootKey.createKey(sImplKeyName, key)) {
231 if (bVerbose) {
232 fprintf(stderr, "ERROR: can't create new implementation entry \"%s\".\n", sImplName.getStr());
234 return 1;
238 OString sLoaderName = (*comp_iter).sLoaderName;
239 OUString usKeyName(OUSTR("UNO/ACTIVATOR"));
240 key.createKey(usKeyName, subKey);
241 subKey.setValue(OUString(), RG_VALUETYPE_STRING,
242 (sal_Char*)sLoaderName.getStr(), sLoaderName.getLength()+1);
244 OString sCompName = (*comp_iter).sComponentName;
245 usKeyName = OUSTR("UNO/LOCATION");
246 key.createKey(usKeyName, subKey);
247 subKey.setValue(OUString(), RG_VALUETYPE_STRING,
248 (sal_Char*)sCompName.getStr(), sCompName.getLength()+1);
250 if ((*comp_iter).vData.size() > 0) {
251 usKeyName = OUSTR("DATA");
252 RegistryKey dataKey, valueKey;
253 key.createKey(usKeyName, dataKey);
255 DataVector::const_iterator data_iter = ((*comp_iter).vData).begin();
256 do {
257 OUString sDataKey(OSToOUS((*data_iter).first));
258 dataKey.createKey(sDataKey, valueKey);
260 OSVector::const_iterator value_iter = ((*data_iter).second).begin();
261 int vlen = (*data_iter).second.size();
262 sal_Char** pValueList = (sal_Char**)rtl_allocateZeroMemory(
263 vlen * sizeof(sal_Char*));
264 int i = 0;
265 do {
266 pValueList[i] = (sal_Char*)rtl_allocateZeroMemory(
267 (*value_iter).getLength()+1 * sizeof(sal_Char));
268 rtl_copyMemory(pValueList[i], (sal_Char*)(*value_iter).getStr(),
269 (*value_iter).getLength()+1);
270 i++;
271 value_iter++;
272 } while (value_iter != (*data_iter).second.end());
274 valueKey.setStringListValue(OUString(), pValueList, vlen);
276 // free memory
277 for (i=0; i<vlen; i++)
278 rtl_freeMemory(pValueList[i]);
279 rtl_freeMemory(pValueList);
281 data_iter++;
282 } while (data_iter != (*comp_iter).vData.end());
285 usKeyName = OUSTR("UNO/SERVICES");
286 key.createKey(usKeyName, subKey);
288 rootKey.createKey(OUSTR("/SERVICES"), serviceKey);
290 OSVector::const_iterator serv_iter = ((*comp_iter).vSupportedServices).begin();
291 OUString usServiceKeyName;
292 do {
293 usServiceKeyName = OSToOUS(*serv_iter);
294 // write service key in impl section
295 subKey.createKey(usServiceKeyName, key);
297 if (serviceKey.openKey(usServiceKeyName, key) == REG_NO_ERROR) {
298 RegistryValueList<sal_Char*> valueList;
299 serviceKey.getStringListValue(usServiceKeyName, valueList);
300 if ( checkImplValue(&valueList, sImplName) ) {
301 serv_iter++;
302 continue;
305 sal_uInt32 nServices = valueList.getLength()+1;
306 sal_Char** pImplList = (sal_Char**)rtl_allocateZeroMemory(
307 nServices * sizeof(sal_Char*));
308 pImplList[0] = (sal_Char*)rtl_allocateZeroMemory(
309 sImplName.getLength()+1 * sizeof(sal_Char));
310 rtl_copyMemory(pImplList[0], (sal_Char*)sImplName.getStr(),
311 sImplName.getLength()+1);
312 for (sal_uInt32 i=0; i < valueList.getLength(); i++) {
313 pImplList[i+1]=valueList.getElement(i);
315 key.setStringListValue(OUString(), pImplList, nServices);
317 // free memory
318 rtl_freeMemory(pImplList[0]);
319 rtl_freeMemory(pImplList);
321 } else {
322 serviceKey.createKey(usServiceKeyName, key);
324 sal_Char* pImplList[1];
325 pImplList[0] = (sal_Char*)rtl_allocateZeroMemory(
326 sImplName.getLength()+1 * sizeof(sal_Char));
327 rtl_copyMemory(pImplList[0], (sal_Char*)sImplName.getStr(),
328 sImplName.getLength()+1);
329 key.setStringListValue(OUString(), pImplList, 1);
331 // free memory
332 rtl_freeMemory(pImplList[0]);
334 serv_iter++;
335 } while (serv_iter != (*comp_iter).vSupportedServices.end());
337 comp_iter++;
338 } while (comp_iter != vDescr.end());
340 key.closeKey();
341 subKey.closeKey();
342 serviceKey.closeKey();
343 rootKey.closeKey();
344 pReg->close();
346 return 0;