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 :
21 : #include <ctype.h>
22 : #include <stdio.h>
23 : #include <stdlib.h>
24 : #include <tools/debug.hxx>
25 : #include <database.hxx>
26 : #include <globals.hxx>
27 : #include <rtl/strbuf.hxx>
28 : #include <osl/file.hxx>
29 :
30 0 : SvIdlDataBase::SvIdlDataBase( const SvCommand& rCmd )
31 : : bExport( sal_False )
32 : , nUniqueId( 0 )
33 : , nVerbosity( rCmd.nVerbosity )
34 0 : , aPersStream( *IDLAPP->pClassMgr, NULL )
35 0 : , pIdTable( NULL )
36 : {
37 0 : sSlotMapFile = rCmd.aSlotMapFile;
38 0 : }
39 :
40 0 : SvIdlDataBase::~SvIdlDataBase()
41 : {
42 0 : aIdFileList.clear();
43 :
44 0 : delete pIdTable;
45 0 : }
46 :
47 : #define ADD_TYPE( Name, OdlName, ParserChar, CName, BasName, BasPost ) \
48 : aTypeList.push_back( new SvMetaType( SvHash_##Name()->GetName(), \
49 : BasName, OdlName, ParserChar, CName, BasName, BasPost ) );
50 :
51 0 : SvMetaTypeMemberList & SvIdlDataBase::GetTypeList()
52 : {
53 0 : if( aTypeList.empty() )
54 : { // fill initially
55 0 : aTypeList.push_back( new SvMetaTypeString() );
56 0 : aTypeList.push_back( new SvMetaTypevoid() );
57 :
58 : // MI: IDispatch::Invoke can not unsigned
59 0 : ADD_TYPE( UINT16, "long", 'h', "unsigned short", "Long", "&" );
60 0 : ADD_TYPE( INT16, "short", 'h', "short", "Integer", "%" );
61 0 : ADD_TYPE( UINT32, "long", 'l', "unsigned long", "Long", "&" );
62 0 : ADD_TYPE( INT32, "long", 'l', "long", "Long", "&" );
63 0 : ADD_TYPE( int, "int", 'i', "int", "Integer", "%" );
64 0 : ADD_TYPE( BOOL, "boolean", 'b', "unsigned char", "Boolean", "" );
65 0 : ADD_TYPE( char, "char", 'c', "char", "Integer", "%" );
66 0 : ADD_TYPE( BYTE, "char", 'c', "unsigned char", "Integer", "%" );
67 0 : ADD_TYPE( float, "float", 'f', "float", "Single", "!" );
68 0 : ADD_TYPE( double, "double", 'F', "double", "Double", "#" );
69 0 : ADD_TYPE( SbxObject, "VARIANT", 'o', "C_Object", "Object", "" );
70 :
71 : // Attention! When adding types all binary data bases get incompatible
72 :
73 : }
74 0 : return aTypeList;
75 : }
76 :
77 0 : SvMetaModule * SvIdlDataBase::GetModule( const OString& rName )
78 : {
79 0 : for( sal_uLong n = 0; n < aModuleList.size(); n++ )
80 0 : if( aModuleList[n]->GetName().getString().equals(rName) )
81 0 : return aModuleList[n];
82 0 : return NULL;
83 : }
84 :
85 : #define DATABASE_SIGNATURE (sal_uInt32)0x13B799F2
86 : #define DATABASE_VER 0x0006
87 0 : sal_Bool SvIdlDataBase::IsBinaryFormat( SvStream & rStm )
88 : {
89 0 : sal_uInt32 nSig = 0;
90 0 : sal_uLong nPos = rStm.Tell();
91 0 : rStm.ReadUInt32( nSig );
92 0 : rStm.Seek( nPos );
93 :
94 0 : return nSig == DATABASE_SIGNATURE;
95 : }
96 :
97 0 : void SvIdlDataBase::Load( SvStream & rStm )
98 : {
99 : DBG_ASSERT( aTypeList.empty(), "type list already initialized" );
100 0 : SvPersistStream aPStm( *IDLAPP->pClassMgr, &rStm );
101 :
102 0 : sal_uInt16 nVersion = 0;
103 0 : sal_uInt32 nSig = 0;
104 :
105 0 : aPStm.ReadUInt32( nSig );
106 0 : aPStm.ReadUInt16( nVersion );
107 0 : if( nSig != DATABASE_SIGNATURE )
108 : {
109 0 : aPStm.SetError( SVSTREAM_FILEFORMAT_ERROR );
110 0 : return;
111 : }
112 0 : if( nVersion != DATABASE_VER )
113 : {
114 0 : aPStm.SetError( SVSTREAM_WRONGVERSION );
115 0 : return;
116 : }
117 0 : aPStm >> aClassList;
118 0 : aPStm >> aTypeList;
119 0 : aPStm >> aAttrList;
120 0 : aPStm >> aModuleList;
121 0 : aPStm.ReadUInt32( nUniqueId );
122 :
123 0 : if( aPStm.IsEof() )
124 0 : aPStm.SetError( SVSTREAM_GENERALERROR );
125 : }
126 :
127 0 : void SvIdlDataBase::Save( SvStream & rStm, sal_uInt32 nFlags )
128 : {
129 0 : SvPersistStream aPStm( *IDLAPP->pClassMgr, &rStm );
130 0 : aPStm.SetContextFlags( nFlags );
131 :
132 0 : aPStm.WriteUInt32( (sal_uInt32)DATABASE_SIGNATURE );
133 0 : aPStm.WriteUInt16( (sal_uInt16)DATABASE_VER );
134 :
135 0 : sal_Bool bOnlyStreamedObjs = sal_False;
136 0 : if( nFlags & IDL_WRITE_CALLING )
137 0 : bOnlyStreamedObjs = sal_True;
138 :
139 0 : if( bOnlyStreamedObjs )
140 : {
141 0 : SvMetaClassMemberList aList;
142 0 : for( sal_uLong n = 0; n < GetModuleList().size(); n++ )
143 : {
144 0 : SvMetaModule * pModule = GetModuleList()[n];
145 0 : if( !pModule->IsImported() )
146 0 : aList.insert( pModule->GetClassList() );
147 : }
148 0 : WriteSvDeclPersistList( aPStm, aList );
149 : }
150 : else
151 0 : WriteSvDeclPersistList( aPStm, aClassList );
152 :
153 0 : aTypeList.WriteObjects( aPStm, bOnlyStreamedObjs );
154 0 : aAttrList.WriteObjects( aPStm, bOnlyStreamedObjs );
155 0 : aModuleList.WriteObjects( aPStm, bOnlyStreamedObjs );
156 0 : aPStm.WriteUInt32( nUniqueId );
157 0 : }
158 :
159 0 : void SvIdlDataBase::SetError( const OString& rError, SvToken * pTok )
160 : {
161 0 : if( pTok->GetLine() > 10000 )
162 0 : aError.SetText( "line count overflow" );
163 :
164 0 : if( aError.nLine < pTok->GetLine()
165 0 : || (aError.nLine == pTok->GetLine() && aError.nColumn < pTok->GetColumn()) )
166 : {
167 0 : aError = SvIdlError( pTok->GetLine(), pTok->GetColumn() );
168 0 : aError.SetText( rError );
169 : }
170 0 : }
171 :
172 0 : void SvIdlDataBase::Push( SvMetaObject * pObj )
173 : {
174 0 : GetStack().Push( pObj );
175 0 : }
176 :
177 0 : sal_Bool SvIdlDataBase::FindId( const OString& rIdName, sal_uLong * pVal )
178 : {
179 0 : if( pIdTable )
180 : {
181 : sal_uInt32 nHash;
182 0 : if( pIdTable->Test( rIdName, &nHash ) )
183 : {
184 0 : *pVal = pIdTable->Get( nHash )->GetValue();
185 0 : return sal_True;
186 : }
187 : }
188 0 : return sal_False;
189 : }
190 :
191 0 : sal_Bool SvIdlDataBase::InsertId( const OString& rIdName, sal_uLong nVal )
192 : {
193 0 : if( !pIdTable )
194 0 : pIdTable = new SvStringHashTable( 20003 );
195 :
196 : sal_uInt32 nHash;
197 0 : if( pIdTable->Insert( rIdName, &nHash ) )
198 : {
199 0 : pIdTable->Get( nHash )->SetValue( nVal );
200 0 : return sal_True;
201 : }
202 0 : return sal_False;
203 : }
204 :
205 0 : sal_Bool SvIdlDataBase::ReadIdFile( const OUString & rFileName )
206 : {
207 0 : OUString aFullName;
208 0 : osl::File::searchFileURL( rFileName, GetPath(), aFullName);
209 0 : osl::FileBase::getSystemPathFromFileURL( aFullName, aFullName );
210 :
211 0 : for ( size_t i = 0, n = aIdFileList.size(); i < n; ++i )
212 0 : if ( aIdFileList[ i ] == rFileName )
213 0 : return sal_True;
214 :
215 0 : aIdFileList.push_back( rFileName );
216 0 : this->AddDepFile( aFullName );
217 0 : SvTokenStream aTokStm( aFullName );
218 0 : if( aTokStm.GetStream().GetError() == SVSTREAM_OK )
219 : {
220 0 : SvToken * pTok = aTokStm.GetToken_Next();
221 :
222 0 : while( !pTok->IsEof() )
223 : {
224 0 : if( pTok->IsChar() && pTok->GetChar() == '#' )
225 : {
226 0 : pTok = aTokStm.GetToken_Next();
227 0 : if( pTok->Is( SvHash_define() ) )
228 : {
229 0 : pTok = aTokStm.GetToken_Next();
230 0 : OString aDefName;
231 0 : if( pTok->IsIdentifier() )
232 0 : aDefName = pTok->GetString();
233 : else
234 : {
235 0 : OString aStr("unexpected token after define");
236 : // set error
237 0 : SetError( aStr, pTok );
238 0 : WriteError( aTokStm );
239 0 : return sal_False;
240 : }
241 :
242 0 : sal_uLong nVal = 0;
243 0 : sal_Bool bOk = sal_True;
244 0 : while( bOk )
245 : {
246 0 : pTok = aTokStm.GetToken_Next();
247 0 : if( pTok->IsIdentifier() )
248 : {
249 : sal_uLong n;
250 0 : if( FindId( pTok->GetString(), &n ) )
251 0 : nVal += n;
252 : else
253 0 : bOk = sal_False;
254 : }
255 0 : else if( pTok->IsChar() )
256 : {
257 0 : if( pTok->GetChar() == '-'
258 0 : || pTok->GetChar() == '/'
259 0 : || pTok->GetChar() == '*'
260 0 : || pTok->GetChar() == '&'
261 0 : || pTok->GetChar() == '|'
262 0 : || pTok->GetChar() == '^'
263 0 : || pTok->GetChar() == '~' )
264 : {
265 0 : OStringBuffer aStr("unknown operator '");
266 0 : aStr.append(pTok->GetChar());
267 0 : aStr.append("'in define");
268 : // set error
269 0 : SetError( aStr.makeStringAndClear(), pTok );
270 0 : WriteError( aTokStm );
271 0 : return sal_False;
272 : }
273 0 : if( pTok->GetChar() != '+'
274 0 : && pTok->GetChar() != '('
275 0 : && pTok->GetChar() != ')' )
276 : // only + is allowed, parentheses are immaterial
277 : // because + is commutative
278 0 : break;
279 : }
280 0 : else if( pTok->IsInteger() )
281 : {
282 0 : nVal += pTok->GetNumber();
283 : }
284 : else
285 0 : break;
286 : }
287 0 : if( bOk )
288 : {
289 0 : if( !InsertId( aDefName, nVal ) )
290 : {
291 0 : OString aStr("hash table overflow: ");
292 0 : SetError( aStr, pTok );
293 0 : WriteError( aTokStm );
294 0 : return sal_False;
295 : }
296 0 : }
297 : }
298 0 : else if( pTok->Is( SvHash_include() ) )
299 : {
300 0 : pTok = aTokStm.GetToken_Next();
301 0 : OStringBuffer aName;
302 0 : if( pTok->IsString() )
303 0 : aName.append(pTok->GetString());
304 0 : else if( pTok->IsChar() && pTok->GetChar() == '<' )
305 : {
306 0 : pTok = aTokStm.GetToken_Next();
307 0 : while( !pTok->IsEof()
308 0 : && !(pTok->IsChar() && pTok->GetChar() == '>') )
309 : {
310 0 : aName.append(pTok->GetTokenAsString());
311 0 : pTok = aTokStm.GetToken_Next();
312 : }
313 0 : if( pTok->IsEof() )
314 : {
315 0 : OString aStr("unexpected eof in #include");
316 : // set error
317 0 : SetError(aStr, pTok);
318 0 : WriteError( aTokStm );
319 0 : return sal_False;
320 : }
321 : }
322 0 : if (!ReadIdFile(OStringToOUString(aName.toString(),
323 0 : RTL_TEXTENCODING_ASCII_US)))
324 : {
325 0 : OStringBuffer aStr("cannot read file: ");
326 0 : aStr.append(aName.makeStringAndClear());
327 0 : SetError(aStr.makeStringAndClear(), pTok);
328 0 : WriteError( aTokStm );
329 0 : return sal_False;
330 0 : }
331 : }
332 : }
333 : else
334 0 : pTok = aTokStm.GetToken_Next();
335 : }
336 : }
337 : else
338 0 : return sal_False;
339 0 : return sal_True;
340 : }
341 :
342 0 : SvMetaType * SvIdlDataBase::FindType( const SvMetaType * pPType,
343 : SvMetaTypeMemberList & rList )
344 : {
345 0 : for( SvMetaTypeMemberList::const_iterator it = rList.begin(); it != rList.end(); ++it )
346 0 : if( *it == pPType )
347 0 : return *it;
348 0 : return NULL;
349 : }
350 :
351 0 : SvMetaType * SvIdlDataBase::FindType( const OString& rName )
352 : {
353 0 : for( SvMetaTypeMemberList::const_iterator it = aTypeList.begin(); it != aTypeList.end(); ++it )
354 0 : if( rName.equals((*it)->GetName().getString()) )
355 0 : return *it;
356 0 : return NULL;
357 : }
358 :
359 0 : SvMetaType * SvIdlDataBase::ReadKnownType( SvTokenStream & rInStm )
360 : {
361 0 : sal_Bool bIn = sal_False;
362 0 : sal_Bool bOut = sal_False;
363 0 : int nCall0 = CALL_VALUE;
364 0 : int nCall1 = CALL_VALUE;
365 0 : sal_Bool bSet = sal_False; // any attribute set
366 :
367 0 : sal_uInt32 nTokPos = rInStm.Tell();
368 0 : SvToken * pTok = rInStm.GetToken_Next();
369 :
370 0 : if( pTok->HasHash() )
371 : {
372 0 : sal_uInt32 nBeginPos = 0; // can not happen with Tell
373 0 : while( nBeginPos != rInStm.Tell() )
374 : {
375 0 : nBeginPos = rInStm.Tell();
376 0 : if( pTok->Is( SvHash_in() ) )
377 : {
378 0 : bIn = sal_True;
379 0 : pTok = rInStm.GetToken_Next();
380 0 : bSet = sal_True;
381 : }
382 0 : if( pTok->Is( SvHash_out() ) )
383 : {
384 0 : bOut = sal_True;
385 0 : pTok = rInStm.GetToken_Next();
386 0 : bSet = sal_True;
387 : }
388 0 : if( pTok->Is( SvHash_inout() ) )
389 : {
390 0 : bIn = sal_True;
391 0 : bOut = sal_True;
392 0 : pTok = rInStm.GetToken_Next();
393 0 : bSet = sal_True;
394 : }
395 : }
396 : }
397 :
398 0 : if( pTok->IsIdentifier() )
399 : {
400 0 : OString aName = pTok->GetString();
401 0 : SvMetaTypeMemberList & rList = GetTypeList();
402 0 : SvMetaTypeMemberList::const_iterator it = rList.begin();
403 0 : SvMetaType * pType = NULL;
404 0 : while( it != rList.end() )
405 : {
406 0 : if( (*it)->GetName().getString().equals(aName) )
407 : {
408 0 : pType = *it;
409 0 : break;
410 : }
411 0 : ++it;
412 : }
413 0 : if( pType )
414 : {
415 0 : pTok = rInStm.GetToken();
416 0 : if( pTok->IsChar() )
417 : {
418 0 : if( pTok->GetChar() == '&' || pTok->GetChar() == '*' )
419 : {
420 0 : nCall0 = (pTok->GetChar() == '&') ? CALL_REFERENCE :
421 0 : CALL_POINTER;
422 0 : rInStm.GetToken_Next();
423 0 : pTok = rInStm.GetToken();
424 0 : if( pTok->GetChar() == '&' || pTok->GetChar() == '*' )
425 : {
426 0 : nCall1 = (pTok->GetChar() == '&') ? CALL_REFERENCE :
427 0 : CALL_POINTER;
428 0 : rInStm.GetToken_Next();
429 : }
430 0 : bSet = sal_True;
431 : }
432 : }
433 :
434 0 : if( !bSet )
435 : // is exactly this type
436 0 : return pType;
437 :
438 : DBG_ASSERT( aTmpTypeList.front(), "mindestens ein Element" );
439 0 : SvMetaTypeRef xType = new SvMetaType( pType->GetName().getString(), 'h', "dummy" );
440 0 : xType->SetRef( pType );
441 0 : xType->SetIn( bIn );
442 0 : xType->SetOut( bOut );
443 0 : xType->SetCall0( nCall0 );
444 0 : xType->SetCall1( nCall1 );
445 :
446 0 : aTmpTypeList.push_back( xType );
447 0 : return xType;
448 0 : }
449 : }
450 0 : rInStm.Seek( nTokPos );
451 0 : return NULL;
452 : }
453 :
454 0 : SvMetaAttribute * SvIdlDataBase::ReadKnownAttr
455 : (
456 : SvTokenStream & rInStm,
457 : SvMetaType * pType /* If pType == NULL, then the type has
458 : still to be read. */
459 : )
460 : {
461 0 : sal_uInt32 nTokPos = rInStm.Tell();
462 :
463 0 : if( !pType )
464 0 : pType = ReadKnownType( rInStm );
465 :
466 0 : if( !pType )
467 : {
468 : // otherwise SlotId?
469 0 : SvToken * pTok = rInStm.GetToken_Next();
470 0 : if( pTok->IsIdentifier() )
471 : {
472 : sal_uLong n;
473 0 : if( FindId( pTok->GetString(), &n ) )
474 : {
475 0 : for( sal_uLong i = 0; i < aAttrList.size(); i++ )
476 : {
477 0 : SvMetaAttribute * pAttr = aAttrList[i];
478 0 : if( pAttr->GetSlotId().getString().equals(pTok->GetString()) )
479 0 : return pAttr;
480 : }
481 : }
482 :
483 0 : OStringBuffer aStr("Nicht gefunden : ");
484 0 : aStr.append(pTok->GetString());
485 0 : OSL_FAIL(aStr.getStr());
486 : }
487 : }
488 :
489 0 : rInStm.Seek( nTokPos );
490 0 : return NULL;
491 : }
492 :
493 0 : SvMetaAttribute* SvIdlDataBase::SearchKnownAttr
494 : (
495 : const SvNumberIdentifier& rId
496 : )
497 : {
498 : sal_uLong n;
499 0 : if( FindId( rId.getString(), &n ) )
500 : {
501 0 : for( sal_uLong i = 0; i < aAttrList.size(); i++ )
502 : {
503 0 : SvMetaAttribute * pAttr = aAttrList[i];
504 0 : if( pAttr->GetSlotId().getString() == rId.getString() )
505 0 : return pAttr;
506 : }
507 : }
508 :
509 0 : return NULL;
510 : }
511 :
512 0 : SvMetaClass * SvIdlDataBase::ReadKnownClass( SvTokenStream & rInStm )
513 : {
514 0 : sal_uInt32 nTokPos = rInStm.Tell();
515 0 : SvToken * pTok = rInStm.GetToken_Next();
516 :
517 0 : if( pTok->IsIdentifier() )
518 0 : for( sal_uLong n = 0; n < aClassList.size(); n++ )
519 : {
520 0 : SvMetaClass * pClass = aClassList[n];
521 0 : if( pClass->GetName().getString().equals(pTok->GetString()) )
522 0 : return pClass;
523 : }
524 :
525 0 : rInStm.Seek( nTokPos );
526 0 : return NULL;
527 : }
528 :
529 0 : void SvIdlDataBase::Write(const OString& rText)
530 : {
531 0 : if( nVerbosity != 0 )
532 0 : fprintf( stdout, "%s", rText.getStr() );
533 0 : }
534 :
535 0 : void SvIdlDataBase::WriteError( const OString& rErrWrn,
536 : const OString& rFileName,
537 : const OString& rErrorText,
538 : sal_uLong nRow, sal_uLong nColumn ) const
539 : {
540 : // error treatment
541 : fprintf( stderr, "\n%s --- %s: ( %ld, %ld )\n",
542 0 : rFileName.getStr(), rErrWrn.getStr(), nRow, nColumn );
543 :
544 0 : if( !rErrorText.isEmpty() )
545 : { // error set
546 0 : fprintf( stderr, "\t%s\n", rErrorText.getStr() );
547 : }
548 0 : }
549 :
550 0 : void SvIdlDataBase::WriteError( SvTokenStream & rInStm )
551 : {
552 : // error treatment
553 0 : OUString aFileName( rInStm.GetFileName() );
554 0 : OStringBuffer aErrorText;
555 0 : sal_uLong nRow = 0, nColumn = 0;
556 :
557 0 : rInStm.SeekEnd();
558 0 : SvToken *pTok = rInStm.GetToken();
559 :
560 : // error position
561 0 : nRow = pTok->GetLine();
562 0 : nColumn = pTok->GetColumn();
563 :
564 0 : if( aError.IsError() )
565 : { // error set
566 : // search error token
567 : // error text
568 0 : if( !aError.GetText().isEmpty() )
569 : {
570 0 : aErrorText.append("may be <");
571 0 : aErrorText.append(aError.GetText());
572 : }
573 0 : SvToken * pPrevTok = NULL;
574 0 : while( pTok != pPrevTok )
575 : {
576 0 : pPrevTok = pTok;
577 0 : if( pTok->GetLine() == aError.nLine
578 0 : && pTok->GetColumn() == aError.nColumn )
579 0 : break;
580 0 : pTok = rInStm.GetToken_PrevAll();
581 : }
582 :
583 : // error position
584 0 : aErrorText.append("> at ( ");
585 0 : aErrorText.append(static_cast<sal_Int64>(aError.nLine));
586 0 : aErrorText.append(", ");
587 0 : aErrorText.append(static_cast<sal_Int64>(aError.nColumn));
588 0 : aErrorText.append(" )");
589 :
590 : // reset error
591 0 : aError = SvIdlError();
592 : }
593 :
594 : WriteError("error", OUStringToOString(aFileName,
595 0 : RTL_TEXTENCODING_UTF8), aErrorText.makeStringAndClear(), nRow, nColumn);
596 :
597 : DBG_ASSERT( pTok, "token must be found" );
598 0 : if( !pTok )
599 0 : return;
600 :
601 : // look for identifier close by
602 0 : if( !pTok->IsIdentifier() )
603 : {
604 0 : rInStm.GetToken_PrevAll();
605 0 : pTok = rInStm.GetToken();
606 : }
607 0 : if( pTok && pTok->IsIdentifier() )
608 : {
609 0 : OString aN = IDLAPP->pHashTable->GetNearString( pTok->GetString() );
610 0 : if( !aN.isEmpty() )
611 0 : fprintf( stderr, "%s versus %s\n", pTok->GetString().getStr(), aN.getStr() );
612 0 : }
613 : }
614 :
615 0 : SvIdlWorkingBase::SvIdlWorkingBase(const SvCommand& rCmd) : SvIdlDataBase(rCmd)
616 : {
617 0 : }
618 :
619 0 : sal_Bool SvIdlWorkingBase::ReadSvIdl( SvTokenStream & rInStm, sal_Bool bImported, const OUString & rPath )
620 : {
621 0 : aPath = rPath; // only valid for this iteration
622 0 : sal_Bool bOk = sal_True;
623 0 : SvToken * pTok = rInStm.GetToken();
624 : // only one import at the very beginning
625 0 : if( pTok->Is( SvHash_import() ) )
626 : {
627 0 : rInStm.GetToken_Next();
628 0 : bOk = rInStm.Read( '(' ); // optional
629 0 : pTok = bOk ? rInStm.GetToken_Next() : NULL;
630 0 : if( pTok && pTok->IsString() )
631 : {
632 0 : OUString aFullName;
633 0 : if( osl::FileBase::E_None == osl::File::searchFileURL(
634 0 : OStringToOUString(pTok->GetString(), RTL_TEXTENCODING_ASCII_US),
635 : rPath,
636 0 : aFullName) )
637 : {
638 0 : osl::FileBase::getSystemPathFromFileURL( aFullName, aFullName );
639 0 : this->AddDepFile(aFullName);
640 0 : SvFileStream aStm( aFullName, STREAM_STD_READ | STREAM_NOCREATE );
641 0 : Load( aStm );
642 0 : if( aStm.GetError() != SVSTREAM_OK )
643 : {
644 0 : if( aStm.GetError() == SVSTREAM_WRONGVERSION )
645 : {
646 0 : OStringBuffer aStr("wrong version, file ");
647 0 : aStr.append(OUStringToOString( aFullName, RTL_TEXTENCODING_UTF8));
648 0 : SetError(aStr.makeStringAndClear(), pTok);
649 0 : WriteError( rInStm );
650 0 : bOk = sal_False;
651 : }
652 : else
653 : {
654 0 : aStm.Seek( 0 );
655 0 : aStm.ResetError();
656 0 : SvTokenStream aTokStm( aStm, aFullName );
657 0 : bOk = ReadSvIdl( aTokStm, sal_True, rPath );
658 : }
659 0 : }
660 : }
661 : else
662 0 : bOk = sal_False;
663 : }
664 : else
665 0 : bOk = sal_False;
666 : }
667 :
668 0 : sal_uInt32 nBeginPos = 0xFFFFFFFF; // can not happen with Tell
669 :
670 0 : while( bOk && nBeginPos != rInStm.Tell() )
671 : {
672 0 : nBeginPos = rInStm.Tell();
673 0 : pTok = rInStm.GetToken();
674 0 : if( pTok->IsEof() )
675 0 : return sal_True;
676 0 : if( pTok->IsEmpty() )
677 0 : bOk = sal_False;
678 :
679 : // only one import at the very beginning
680 0 : if( pTok->Is( SvHash_module() ) )
681 : {
682 0 : SvMetaModuleRef aModule = new SvMetaModule( rInStm.GetFileName(), bImported );
683 0 : if( aModule->ReadSvIdl( *this, rInStm ) )
684 0 : GetModuleList().push_back( aModule );
685 : else
686 0 : bOk = sal_False;
687 : }
688 : else
689 0 : bOk = sal_False;
690 : }
691 0 : if( !bOk || !pTok->IsEof() )
692 : {
693 : // error treatment
694 0 : WriteError( rInStm );
695 0 : return sal_False;
696 : }
697 0 : return sal_True;
698 : }
699 :
700 0 : sal_Bool SvIdlWorkingBase::WriteSvIdl( SvStream & rOutStm )
701 : {
702 0 : if( rOutStm.GetError() != SVSTREAM_OK )
703 0 : return sal_False;
704 :
705 0 : SvStringHashList aList;
706 0 : if( GetIdTable() )
707 : {
708 0 : GetIdTable()->FillHashList( &aList );
709 0 : for ( size_t i = 0, n = aList.size(); i < n; ++i )
710 : {
711 0 : SvStringHashEntry* pEntry = aList[ i ];
712 0 : rOutStm.WriteCharPtr( "#define " ).WriteCharPtr( pEntry->GetName().getStr() )
713 0 : .WriteChar( '\t' )
714 0 : .WriteCharPtr( OString::number(pEntry->GetValue()).getStr() )
715 0 : << endl;
716 : }
717 : }
718 :
719 0 : for( sal_uLong n = 0; n < GetModuleList().size(); n++ )
720 : {
721 0 : SvMetaModule * pModule = GetModuleList()[n];
722 0 : pModule->WriteSvIdl( *this, rOutStm, 0 );
723 : }
724 0 : return sal_True;
725 : }
726 :
727 0 : sal_Bool SvIdlWorkingBase::WriteSfx( SvStream & rOutStm )
728 : {
729 0 : if( rOutStm.GetError() != SVSTREAM_OK )
730 0 : return sal_False;
731 :
732 : // reset all tmp variables for writing
733 0 : WriteReset();
734 0 : SvMemoryStream aTmpStm( 256000, 256000 );
735 : sal_uLong n;
736 0 : for( n = 0; n < GetModuleList().size(); n++ )
737 : {
738 0 : SvMetaModule * pModule = GetModuleList()[n];
739 0 : if( !pModule->IsImported() )
740 0 : pModule->WriteSfx( *this, aTmpStm );
741 0 : aTmpStm.Seek( 0 );
742 : }
743 0 : for( n = 0; n < aUsedTypes.size(); n++ )
744 : {
745 0 : SvMetaType * pType = aUsedTypes[n];
746 0 : pType->WriteSfx( *this, rOutStm );
747 : }
748 0 : aUsedTypes.clear();
749 0 : rOutStm.WriteStream( aTmpStm );
750 0 : return sal_True;
751 : }
752 :
753 0 : sal_Bool SvIdlWorkingBase::WriteHelpIds( SvStream& rOutStm )
754 : {
755 0 : if( rOutStm.GetError() != SVSTREAM_OK )
756 0 : return sal_False;
757 :
758 0 : HelpIdTable aIdTable;
759 : sal_uLong n;
760 0 : for( n = 0; n < GetModuleList().size(); n++ )
761 : {
762 0 : SvMetaModule * pModule = GetModuleList()[n];
763 0 : pModule->WriteHelpIds( *this, rOutStm, aIdTable );
764 : }
765 :
766 0 : const SvMetaAttributeMemberList & rAttrList = GetAttrList();
767 0 : for( n = 0; n < rAttrList.size(); n++ )
768 : {
769 0 : SvMetaAttribute * pAttr = rAttrList[n];
770 0 : pAttr->WriteHelpId( *this, rOutStm, aIdTable );
771 : }
772 :
773 0 : return sal_True;
774 : }
775 :
776 0 : sal_Bool SvIdlWorkingBase::WriteSfxItem( SvStream & )
777 : {
778 0 : return sal_False;
779 : }
780 :
781 0 : void SvIdlDataBase::StartNewFile( const OUString& rName )
782 : {
783 0 : bExport = ( aExportFile.equalsIgnoreAsciiCase( rName ) );
784 0 : }
785 :
786 0 : void SvIdlDataBase::AppendAttr( SvMetaAttribute *pAttr )
787 : {
788 0 : aAttrList.push_back( pAttr );
789 0 : if ( bExport )
790 0 : pAttr->SetNewAttribute( sal_True );
791 0 : }
792 :
793 0 : sal_Bool SvIdlWorkingBase::WriteCSV( SvStream& rStrm )
794 : {
795 0 : SvMetaAttributeMemberList &rList = GetAttrList();
796 0 : sal_uLong nCount = rList.size();
797 0 : for ( sal_uLong n=0; n<nCount; n++ )
798 : {
799 0 : if ( rList[n]->IsNewAttribute() )
800 : {
801 0 : rList[n]->WriteCSV( *this, rStrm );
802 : }
803 : }
804 :
805 0 : if ( rStrm.GetError() != SVSTREAM_OK )
806 0 : return sal_False;
807 : else
808 0 : return sal_True;
809 : }
810 :
811 0 : sal_Bool SvIdlWorkingBase::WriteDocumentation( SvStream & rOutStm )
812 : {
813 0 : if( rOutStm.GetError() != SVSTREAM_OK )
814 0 : return sal_False;
815 :
816 0 : for( sal_uLong n = 0; n < GetModuleList().size(); n++ )
817 : {
818 0 : SvMetaModule * pModule = GetModuleList()[n];
819 0 : if( !pModule->IsImported() )
820 0 : pModule->Write( *this, rOutStm, 0, WRITE_DOCU );
821 : }
822 0 : return sal_True;
823 : }
824 :
825 0 : void SvIdlDataBase::AddDepFile(OUString const& rFileName)
826 : {
827 0 : m_DepFiles.insert(rFileName);
828 0 : }
829 :
830 : struct WriteDep
831 : {
832 : SvFileStream & m_rStream;
833 0 : explicit WriteDep(SvFileStream & rStream) : m_rStream(rStream) { }
834 0 : void operator() (OUString const& rItem)
835 : {
836 0 : m_rStream.WriteCharPtr( " \\\n " );
837 0 : m_rStream.WriteCharPtr( OUStringToOString(rItem, RTL_TEXTENCODING_UTF8).getStr() );
838 0 : }
839 : };
840 :
841 : // write a dummy target for one included file, so the incremental build does
842 : // not break with "No rule to make target" if the included file is removed
843 : struct WriteDummy
844 : {
845 : SvFileStream & m_rStream;
846 0 : explicit WriteDummy(SvFileStream & rStream) : m_rStream(rStream) { }
847 0 : void operator() (OUString const& rItem)
848 : {
849 0 : m_rStream.WriteCharPtr( OUStringToOString(rItem, RTL_TEXTENCODING_UTF8).getStr() );
850 0 : m_rStream.WriteCharPtr( " :\n\n" );
851 0 : }
852 : };
853 :
854 0 : bool SvIdlDataBase::WriteDepFile(
855 : SvFileStream & rStream, OUString const& rTarget)
856 : {
857 0 : rStream.WriteCharPtr( OUStringToOString(rTarget, RTL_TEXTENCODING_UTF8).getStr() );
858 0 : rStream.WriteCharPtr( " :" );
859 0 : ::std::for_each(m_DepFiles.begin(), m_DepFiles.end(), WriteDep(rStream));
860 0 : rStream.WriteCharPtr( "\n\n" );
861 0 : ::std::for_each(m_DepFiles.begin(), m_DepFiles.end(), WriteDummy(rStream));
862 0 : return rStream.GetError() == SVSTREAM_OK;
863 : }
864 :
865 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|