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