Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
5 : : * This Source Code Form is subject to the terms of the Mozilla Public
6 : : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
11 : : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : : * contributor license agreements. See the NOTICE file distributed
13 : : * with this work for additional information regarding copyright
14 : : * ownership. The ASF licenses this file to you under the Apache
15 : : * License, Version 2.0 (the "License"); you may not use this file
16 : : * except in compliance with the License. You may obtain a copy of
17 : : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : : */
19 : :
20 : : #include <stdio.h>
21 : : #include <osl/file.hxx>
22 : : #include <osl/process.h>
23 : : #include <codemaker/typemanager.hxx>
24 : : #include <codemaker/dependency.hxx>
25 : :
26 : : #include <rtl/strbuf.hxx>
27 : :
28 : : #if defined(SAL_W32)
29 : : #include <io.h>
30 : : #include <direct.h>
31 : : #include <errno.h>
32 : : #endif
33 : :
34 : : #ifdef UNX
35 : : #include <stdlib.h>
36 : : #include <sys/stat.h>
37 : : #include <errno.h>
38 : : #include <unistd.h>
39 : : #endif
40 : :
41 : : #include "specialtypemanager.hxx"
42 : : #include "rdboptions.hxx"
43 : : #include "rdbtype.hxx"
44 : :
45 : : #define PATH_DELEMITTER '/'
46 : :
47 : : using namespace osl;
48 : :
49 : : using ::rtl::OUString;
50 : : using ::rtl::OString;
51 : : using ::rtl::OStringBuffer;
52 : : using ::rtl::OUStringToOString;
53 : : using ::rtl::OStringToOUString;
54 : :
55 : 2 : FileStream listFile;
56 : 2 : RegistryKey rootKey;
57 : 2 : Registry regFile;
58 : : sal_Bool useSpecial;
59 : : TypeManager* pTypeMgr = NULL;
60 : 2 : StringList dirEntries;
61 : 2 : StringSet filterTypes;
62 : :
63 : 0 : OString getFullNameOfApplicatRdb()
64 : : {
65 : 0 : OUString bootReg;
66 : 0 : OUString uTmpStr;
67 [ # # ][ # # ]: 0 : if( osl_getExecutableFile(&uTmpStr.pData) == osl_Process_E_None )
68 : : {
69 : 0 : sal_uInt32 lastIndex = uTmpStr.lastIndexOf(PATH_DELEMITTER);
70 : 0 : OUString tmpReg;
71 : :
72 [ # # ]: 0 : if ( lastIndex > 0 )
73 : : {
74 : 0 : tmpReg =uTmpStr.copy(0, lastIndex + 1);
75 : : }
76 : :
77 [ # # ]: 0 : tmpReg += OUString( RTL_CONSTASCII_USTRINGPARAM("applicat.rdb") );
78 : :
79 [ # # ]: 0 : FileBase::getSystemPathFromFileURL(tmpReg, bootReg);
80 : : }
81 : :
82 [ # # ]: 0 : return OUStringToOString(bootReg, RTL_TEXTENCODING_ASCII_US);
83 : : }
84 : :
85 : 2 : void initFilterTypes(RdbOptions* pOptions)
86 : : {
87 [ + - ][ - + ]: 2 : if (pOptions->isValid("-FT"))
88 : : {
89 [ # # ]: 0 : OString fOption(pOptions->getOption("-FT"));
90 : 0 : sal_Int32 nIndex = 0;
91 [ # # ]: 0 : do
92 : : {
93 [ # # ]: 0 : filterTypes.insert( fOption.getToken( 0, ';', nIndex ).replace('.', '/') );
94 : : }
95 : 0 : while ( nIndex >= 0 );
96 : : }
97 [ + - ][ - + ]: 2 : if (pOptions->isValid("-F"))
98 : : {
99 [ # # ][ # # ]: 0 : FILE *f = fopen(pOptions->getOption("-F").getStr(), "r");
100 : :
101 [ # # ]: 0 : if (f)
102 : : {
103 : : sal_Char buffer[1024+1];
104 [ # # ]: 0 : sal_Char *pBuf = fgets(buffer, 1024, f);
105 : 0 : sal_Char *s = NULL;
106 : 0 : sal_Char *p = NULL;
107 [ # # ][ # # ]: 0 : while ( pBuf && !feof(f))
[ # # ]
108 : : {
109 : 0 : p = pBuf;
110 [ # # ][ # # ]: 0 : if (*p != '\n' && *p != '\r')
111 : : {
112 [ # # ][ # # ]: 0 : while (*p == ' ' && *p =='\t')
[ # # ]
113 : 0 : p++;
114 : :
115 : 0 : s = p;
116 [ # # ][ # # ]: 0 : while (*p != '\n' && *p != '\r' && *p != ' ' && *p != '\t')
[ # # ][ # # ]
[ # # ]
117 : 0 : p++;
118 : :
119 : 0 : *p = '\0';
120 [ # # ]: 0 : filterTypes.insert( OString(s).replace('.', '/') );
121 : : }
122 : :
123 [ # # ]: 0 : pBuf = fgets(buffer, 1024, f);
124 : : }
125 : :
126 [ # # ]: 0 : fclose(f);
127 : : }
128 : : }
129 : 2 : }
130 : :
131 : 222 : sal_Bool checkFilterTypes(const OString& type)
132 : : {
133 : 222 : StringSet::iterator iter = filterTypes.begin();
134 [ - + ]: 222 : while ( iter != filterTypes.end() )
135 : : {
136 [ # # ]: 0 : if ( type.indexOf( *iter ) == 0 )
137 : : {
138 : 0 : return sal_True;
139 : : }
140 : :
141 : 0 : ++iter;
142 : : }
143 : :
144 : 222 : return sal_False;
145 : : }
146 : :
147 : 2 : void cleanUp( sal_Bool bError)
148 : : {
149 [ + - ]: 2 : if ( pTypeMgr )
150 : : {
151 [ + - ][ + - ]: 2 : delete pTypeMgr;
152 : : }
153 [ - + ]: 2 : if (useSpecial)
154 : : {
155 [ # # ][ # # ]: 0 : pTypeMgr = new SpecialTypeManager();
156 : : }else
157 : : {
158 [ + - ][ + - ]: 2 : pTypeMgr = new RegistryTypeManager();
159 : : }
160 : :
161 [ + - ]: 2 : if ( rootKey.isValid() )
162 : : {
163 [ + - ]: 2 : rootKey.closeKey();
164 : : }
165 [ + - ]: 2 : if ( regFile.isValid() )
166 : : {
167 [ - + ]: 2 : if ( bError )
168 : : {
169 [ # # ]: 0 : regFile.destroy(OUString());
170 : : } else
171 : : {
172 [ + - ]: 2 : regFile.close();
173 : : }
174 : : }
175 [ + - ][ - + ]: 2 : if ( listFile.isValid() )
176 : : {
177 [ # # ]: 0 : listFile.close();
178 : 0 : unlink(listFile.getName().getStr());
179 : : }
180 : :
181 : 2 : StringList::reverse_iterator iter = dirEntries.rbegin();
182 [ + - ][ - + ]: 2 : while ( iter != dirEntries.rend() )
183 : : {
184 [ # # ][ # # ]: 0 : if (rmdir((char*)(*iter).getStr()) == -1)
185 : : {
186 : 0 : break;
187 : : }
188 : :
189 [ # # ]: 0 : ++iter;
190 : : }
191 : 2 : }
192 : :
193 : 2 : OString createFileName(const OString& path)
194 : : {
195 : 2 : OString fileName(path);
196 : :
197 : : sal_Char token;
198 : : #ifdef SAL_UNX
199 : 2 : fileName = fileName.replace('\\', '/');
200 : 2 : token = '/';
201 : : #else
202 : : fileName = fileName.replace('/', '\\');
203 : : token = '\\';
204 : : #endif
205 : :
206 : 2 : OStringBuffer nameBuffer( path.getLength() );
207 : :
208 : 2 : sal_Int32 nIndex = 0;
209 [ + - ]: 16 : do
210 : : {
211 [ + - ]: 18 : nameBuffer.append(fileName.getToken( 0, token, nIndex ).getStr());
212 [ + + ]: 18 : if ( nIndex == -1 ) break;
213 : :
214 [ + + ][ + - ]: 16 : if (nameBuffer.getLength() == 0 || OString(".") == nameBuffer.getStr())
[ - + ][ + + ]
[ + + ][ + + ]
[ + + # #
# # # # ]
215 : : {
216 [ + - ]: 2 : nameBuffer.append(token);
217 : 2 : continue;
218 : : }
219 : :
220 : : #if defined(SAL_UNX)
221 [ + - ]: 14 : if (mkdir((char*)nameBuffer.getStr(), 0777) == -1)
222 : : #else
223 : : if (mkdir((char*)nameBuffer.getStr()) == -1)
224 : : #endif
225 : : {
226 [ - + ]: 14 : if ( errno == ENOENT )
227 : 0 : return OString();
228 : : } else
229 : : {
230 [ # # ]: 0 : dirEntries.push_back(nameBuffer.getStr());
231 : : }
232 : :
233 [ + - ]: 14 : nameBuffer.append(token);
234 : : }
235 : : while ( nIndex >= 0 );
236 : :
237 : 2 : return fileName;
238 : : }
239 : :
240 : 0 : sal_Bool produceAllTypes(const OString& typeName,
241 : : TypeManager& typeMgr,
242 : : TypeDependency& typeDependencies,
243 : : RdbOptions* pOptions,
244 : : sal_Bool bFullScope,
245 : : FileStream& o,
246 : : RegistryKey& regKey,
247 : : StringSet& filterTypes2)
248 : : throw( CannotDumpException )
249 : : {
250 [ # # ][ # # ]: 0 : if (!produceType(typeName, typeMgr, typeDependencies, pOptions, o, regKey, filterTypes2))
251 : : {
252 : : fprintf(stderr, "%s ERROR: %s\n",
253 [ # # ]: 0 : pOptions->getProgramName().getStr(),
254 [ # # ]: 0 : OString("cannot dump Type '" + typeName + "'").getStr());
255 [ # # ]: 0 : cleanUp(sal_True);
256 : 0 : exit(99);
257 : : }
258 : :
259 [ # # ]: 0 : RegistryKey typeKey = typeMgr.getTypeKey(typeName);
260 [ # # ]: 0 : RegistryKeyNames subKeys;
261 : :
262 [ # # ][ # # ]: 0 : if (typeKey.getKeyNames(OUString(), subKeys))
263 : 0 : return sal_False;
264 : :
265 : 0 : OString tmpName;
266 [ # # ]: 0 : for (sal_uInt32 i=0; i < subKeys.getLength(); i++)
267 : : {
268 [ # # ]: 0 : tmpName = OUStringToOString(subKeys.getElement(i), RTL_TEXTENCODING_UTF8);
269 : :
270 [ # # ][ # # ]: 0 : if (pOptions->isValid("-B"))
271 : 0 : tmpName = tmpName.copy(tmpName.indexOf('/', 1) + 1);
272 : : else
273 : 0 : tmpName = tmpName.copy(1);
274 : :
275 [ # # ]: 0 : if (bFullScope)
276 : : {
277 [ # # ]: 0 : if (!produceAllTypes(tmpName, typeMgr, typeDependencies, pOptions, sal_True,
278 [ # # ]: 0 : o, regKey, filterTypes2))
279 : 0 : return sal_False;
280 : : } else
281 : : {
282 [ # # ][ # # ]: 0 : if (!produceType(tmpName, typeMgr, typeDependencies, pOptions, o, regKey, filterTypes2))
283 : 0 : return sal_False;
284 : : }
285 : : }
286 : :
287 [ # # ][ # # ]: 0 : return sal_True;
288 : : }
289 : :
290 : :
291 : : #if (defined UNX)
292 : 2 : int main( int argc, char * argv[] )
293 : : #else
294 : : int __cdecl main( int argc, char * argv[] )
295 : : #endif
296 : : {
297 [ + - ]: 2 : RdbOptions options;
298 : :
299 : : try
300 : : {
301 [ + - ][ - + ]: 2 : if (!options.initOptions(argc, argv))
302 : : {
303 [ # # ]: 0 : cleanUp(sal_True);
304 : 0 : exit(1);
305 : : }
306 : : }
307 [ # # ]: 0 : catch(const IllegalArgument& e)
308 : : {
309 [ # # ]: 0 : fprintf(stderr, "Illegal option: %s\n", e.m_message.getStr());
310 [ # # ]: 0 : cleanUp(sal_True);
311 : 0 : exit(99);
312 : : }
313 : :
314 [ + - ]: 2 : TypeDependency typeDependencies;
315 : :
316 : 2 : OString bootReg;
317 : :
318 [ - + ][ + - ]: 2 : if ( options.isValid("-R") )
319 : : {
320 [ # # ]: 0 : bootReg = options.getOption("-R");
321 : : } else
322 : : {
323 [ + - ][ - + ]: 2 : if (options.getInputFiles().empty())
324 : : {
325 [ # # ]: 0 : bootReg = getFullNameOfApplicatRdb();
326 : : }
327 : : }
328 : :
329 [ - + ]: 2 : if ( !bootReg.isEmpty() )
330 : : {
331 [ # # ][ # # ]: 0 : pTypeMgr = new SpecialTypeManager();
332 : 0 : useSpecial = sal_True;
333 : : } else
334 : : {
335 [ + - ][ + - ]: 2 : pTypeMgr = new RegistryTypeManager();
336 : 2 : useSpecial = sal_False;
337 : : }
338 : :
339 : 2 : TypeManager& typeMgr = *pTypeMgr;
340 : :
341 [ - + ][ # # ]: 2 : if ( useSpecial && !typeMgr.init( bootReg ) )
[ # # ][ - + ]
342 : : {
343 [ # # ][ # # ]: 0 : fprintf(stderr, "%s : init typemanager failed, check your environment for bootstrapping uno.\n", options.getProgramName().getStr());
344 [ # # ]: 0 : cleanUp(sal_True);
345 : 0 : exit(99);
346 : : }
347 [ + - ][ + - ]: 2 : if ( !useSpecial && !typeMgr.init(!options.isValid("-T"), options.getInputFiles()))
[ + - ][ + - ]
[ - + ][ + - ]
[ + - ][ - +
# # # # ]
348 : : {
349 [ # # ][ # # ]: 0 : fprintf(stderr, "%s : init registries failed, check your registry files.\n", options.getProgramName().getStr());
350 [ # # ]: 0 : cleanUp(sal_True);
351 : 0 : exit(99);
352 : : }
353 : :
354 [ + - ]: 2 : initFilterTypes(&options);
355 : :
356 [ + - ][ + - ]: 2 : if (options.isValid("-B"))
357 : : {
358 [ + - ][ + - ]: 2 : typeMgr.setBase(options.getOption("-B"));
359 : : }
360 : :
361 [ + - ][ - + ]: 2 : if ( !options.isValid("-O") )
362 : : {
363 : : fprintf(stderr, "%s ERROR: %s\n",
364 [ # # ]: 0 : options.getProgramName().getStr(),
365 [ # # ]: 0 : "no output file is specified.");
366 [ # # ]: 0 : cleanUp(sal_True);
367 : 0 : exit(99);
368 : : }
369 : :
370 [ - + ]: 2 : if ( options.generateTypeList() )
371 : : {
372 [ # # ][ # # ]: 0 : OString fileName = createFileName( options.getOption("-O") );
373 [ # # ]: 0 : listFile.open(fileName);
374 : :
375 [ # # ][ # # ]: 0 : if ( !listFile.isValid() )
376 : : {
377 : : fprintf(stderr, "%s ERROR: %s\n",
378 [ # # ]: 0 : options.getProgramName().getStr(),
379 [ # # ]: 0 : "could not open output file.");
380 [ # # ]: 0 : cleanUp(sal_True);
381 : 0 : exit(99);
382 : 0 : }
383 : : } else
384 : : {
385 [ + - ][ + - ]: 2 : OUString fileName( OStringToOUString(createFileName( options.getOption("-O") ), RTL_TEXTENCODING_UTF8) );
[ + - ]
386 [ - + ][ + - ]: 2 : if ( regFile.create(fileName) )
387 : : {
388 : : fprintf(stderr, "%s ERROR: %s\n",
389 [ # # ]: 0 : options.getProgramName().getStr(),
390 [ # # ]: 0 : "could not create registry output file.");
391 [ # # ]: 0 : cleanUp(sal_True);
392 : 0 : exit(99);
393 : : }
394 : :
395 : :
396 [ + - ][ + - ]: 2 : if (options.isValid("-b"))
397 : : {
398 [ + - ]: 2 : RegistryKey tmpKey;
399 [ + - ]: 2 : regFile.openRootKey(tmpKey);
400 : :
401 [ + - ][ + - ]: 2 : tmpKey.createKey( OStringToOUString(options.getOption("-b"), RTL_TEXTENCODING_UTF8), rootKey);
[ + - ][ + - ]
402 : : } else
403 : : {
404 [ # # ]: 0 : regFile.openRootKey(rootKey);
405 : 2 : }
406 : : }
407 : :
408 : : try
409 : : {
410 [ + - ][ + - ]: 2 : if (options.isValid("-T"))
411 : : {
412 [ + - ]: 2 : OString tOption(options.getOption("-T"));
413 : 2 : OString typeName, tmpName;
414 : 2 : sal_Bool ret = sal_False;
415 : 2 : sal_Int32 nIndex = 0;
416 [ + + ]: 132 : do
417 : : {
418 : 132 : typeName = tOption.getToken( 0, ';', nIndex);
419 : 132 : sal_Int32 lastIndex = typeName.lastIndexOf('.');
420 : 132 : tmpName = typeName.copy( lastIndex+1 );
421 [ - + ]: 132 : if (tmpName == "*")
422 : : {
423 [ # # ]: 0 : if (!bootReg.isEmpty())
424 : : {
425 : : fprintf(stderr, "%s ERROR: %s\n",
426 [ # # ]: 0 : options.getProgramName().getStr(),
427 [ # # ]: 0 : "dumping all types of a scope is not possible if -R option is used.");
428 : 0 : exit(99);
429 : : }
430 : : // produce this type and his scope, but the scope is not recursively generated.
431 [ # # ]: 0 : if (typeName.equals("*"))
432 : : {
433 : 0 : tmpName = "/";
434 : : } else
435 : : {
436 : 0 : tmpName = typeName.copy(0, typeName.lastIndexOf('.')).replace('.', '/');
437 [ # # ]: 0 : if (tmpName.isEmpty())
438 : 0 : tmpName = "/";
439 : : else
440 : 0 : tmpName.replace('.', '/');
441 : : }
442 : : ret = produceAllTypes(tmpName, typeMgr, typeDependencies, &options, sal_False,
443 [ # # ]: 0 : listFile, rootKey, filterTypes);
444 : : } else
445 : : {
446 : : // produce only this type
447 : : ret = produceType(typeName.replace('.', '/'), typeMgr, typeDependencies,
448 [ + - ]: 132 : &options, listFile, rootKey, filterTypes);
449 : : }
450 : :
451 [ - + ]: 132 : if (!ret)
452 : : {
453 : : fprintf(stderr, "%s ERROR: %s\n",
454 [ # # ]: 0 : options.getProgramName().getStr(),
455 [ # # ]: 0 : OString("cannot dump Type '" + typeName + "'").getStr());
456 [ # # ]: 0 : cleanUp(sal_True);
457 : 0 : exit(99);
458 : : }
459 : : }
460 : 2 : while ( nIndex >= 0 );
461 : : } else
462 [ # # ][ # # ]: 0 : if (options.isValid("-X"))
463 : : {
464 : : } else
465 : : {
466 [ # # ]: 0 : if (bootReg.isEmpty())
467 : : {
468 : : // produce all types
469 [ # # ]: 0 : if (!produceAllTypes("/", typeMgr, typeDependencies, &options, sal_True,
470 [ # # ]: 0 : listFile, rootKey, filterTypes))
471 : : {
472 : : fprintf(stderr, "%s ERROR: %s\n",
473 [ # # ]: 0 : options.getProgramName().getStr(),
474 [ # # ]: 0 : "an error occurs while dumping all types.");
475 : 0 : exit(99);
476 : : }
477 : : } else
478 : : {
479 : : fprintf(stderr, "%s ERROR: %s\n",
480 [ # # ]: 0 : options.getProgramName().getStr(),
481 [ # # ]: 0 : "dumping all types is not possible if -R option is used.");
482 : 0 : exit(99);
483 : : }
484 : : }
485 : : }
486 [ # # ]: 0 : catch(const CannotDumpException& e)
487 : : {
488 : : fprintf(stderr, "%s ERROR: %s\n",
489 [ # # ]: 0 : options.getProgramName().getStr(),
490 [ # # ]: 0 : e.m_message.getStr());
491 [ # # ]: 0 : cleanUp(sal_True);
492 : 0 : exit(99);
493 : : }
494 : :
495 [ + - ]: 2 : cleanUp(sal_False);
496 [ + - ][ + - ]: 2 : return 0;
497 [ + - ][ + - ]: 6 : }
498 : :
499 : :
500 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|