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/fsys.hxx>
25 : #include <tools/debug.hxx>
26 : #include <database.hxx>
27 : #include <globals.hxx>
28 : #include <rtl/strbuf.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 32030 : SvMetaTypeMemberList & SvIdlDataBase::GetTypeList()
53 : {
54 32030 : 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 32030 : return aTypeList;
76 : }
77 :
78 8 : SvMetaModule * SvIdlDataBase::GetModule( const rtl::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 : return;
112 : }
113 0 : if( nVersion != DATABASE_VER )
114 : {
115 0 : aPStm.SetError( SVSTREAM_WRONGVERSION );
116 : 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 5025 : void SvIdlDataBase::SetError( const rtl::OString& rError, SvToken * pTok )
161 : {
162 5025 : if( pTok->GetLine() > 10000 )
163 713 : aError.SetText( "hgchcg" );
164 :
165 5091 : if( aError.nLine < pTok->GetLine()
166 66 : || (aError.nLine == pTok->GetLine() && aError.nColumn < pTok->GetColumn()) )
167 : {
168 4992 : aError = SvIdlError( pTok->GetLine(), pTok->GetColumn() );
169 4992 : aError.SetText( rError );
170 : }
171 5025 : }
172 :
173 8 : void SvIdlDataBase::Push( SvMetaObject * pObj )
174 : {
175 8 : GetStack().Push( pObj );
176 8 : }
177 :
178 42209 : sal_Bool SvIdlDataBase::FindId( const rtl::OString& rIdName, sal_uLong * pVal )
179 : {
180 42209 : if( pIdTable )
181 : {
182 : sal_uInt32 nHash;
183 42209 : if( pIdTable->Test( rIdName, &nHash ) )
184 : {
185 41826 : *pVal = pIdTable->Get( nHash )->GetValue();
186 41826 : return sal_True;
187 : }
188 : }
189 383 : return sal_False;
190 : }
191 :
192 20780 : sal_Bool SvIdlDataBase::InsertId( const rtl::OString& rIdName, sal_uLong nVal )
193 : {
194 20780 : if( !pIdTable )
195 8 : pIdTable = new SvStringHashTable( 20003 );
196 :
197 : sal_uInt32 nHash;
198 20780 : if( pIdTable->Insert( rIdName, &nHash ) )
199 : {
200 20780 : pIdTable->Get( nHash )->SetValue( nVal );
201 20780 : return sal_True;
202 : }
203 0 : return sal_False;
204 : }
205 :
206 196 : sal_Bool SvIdlDataBase::ReadIdFile( const String & rFileName )
207 : {
208 196 : DirEntry aFullName( rFileName );
209 196 : aFullName.Find( GetPath() );
210 :
211 1220 : for ( size_t i = 0, n = aIdFileList.size(); i < n; ++i )
212 1117 : if ( *aIdFileList[ i ] == rFileName )
213 93 : return sal_True;
214 :
215 103 : aIdFileList.push_back( new String( rFileName ) );
216 :
217 103 : this->AddDepFile(aFullName.GetFull());
218 103 : SvTokenStream aTokStm( aFullName.GetFull() );
219 103 : if( aTokStm.GetStream().GetError() == SVSTREAM_OK )
220 : {
221 103 : SvToken * pTok = aTokStm.GetToken_Next();
222 :
223 23692 : while( !pTok->IsEof() )
224 : {
225 23486 : if( pTok->IsChar() && pTok->GetChar() == '#' )
226 : {
227 21374 : pTok = aTokStm.GetToken_Next();
228 21374 : if( pTok->Is( SvHash_define() ) )
229 : {
230 20802 : pTok = aTokStm.GetToken_Next();
231 20802 : rtl::OString aDefName;
232 20802 : if( pTok->IsIdentifier() )
233 20802 : aDefName = pTok->GetString();
234 : else
235 : {
236 : rtl::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 20802 : sal_uLong nVal = 0;
245 20802 : sal_Bool bOk = sal_True;
246 128530 : while( bOk )
247 : {
248 107706 : pTok = aTokStm.GetToken_Next();
249 107706 : if( pTok->IsIdentifier() )
250 : {
251 : sal_uLong n;
252 17244 : if( FindId( pTok->GetString(), &n ) )
253 17222 : nVal += n;
254 : else
255 22 : bOk = sal_False;
256 : }
257 90462 : else if( pTok->IsChar() )
258 : {
259 490812 : if( pTok->GetChar() == '-'
260 70116 : || pTok->GetChar() == '/'
261 70116 : || pTok->GetChar() == '*'
262 70116 : || pTok->GetChar() == '&'
263 70116 : || pTok->GetChar() == '|'
264 70116 : || pTok->GetChar() == '^'
265 70116 : || pTok->GetChar() == '~' )
266 : {
267 0 : rtl::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 159818 : if( pTok->GetChar() != '+'
276 53240 : && pTok->GetChar() != '('
277 36462 : && pTok->GetChar() != ')' )
278 : // only + is allowed, parentheses are immaterial
279 : // because + is commutative
280 19702 : break;
281 : }
282 20346 : else if( pTok->IsInteger() )
283 : {
284 19268 : nVal += pTok->GetNumber();
285 : }
286 : else
287 1078 : break;
288 : }
289 20802 : if( bOk )
290 : {
291 20780 : if( !InsertId( aDefName, nVal ) )
292 : {
293 0 : rtl::OString aStr(RTL_CONSTASCII_STRINGPARAM("hash table overflow: "));
294 0 : SetError( aStr, pTok );
295 0 : WriteError( aTokStm );
296 0 : return sal_False;
297 : }
298 20802 : }
299 : }
300 572 : else if( pTok->Is( SvHash_include() ) )
301 : {
302 185 : pTok = aTokStm.GetToken_Next();
303 185 : rtl::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 3096 : while( !pTok->IsEof()
310 1548 : && !(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 : rtl::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(rtl::OStringToOUString(aName.toString(),
326 370 : RTL_TEXTENCODING_ASCII_US)))
327 : {
328 : rtl::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 2112 : pTok = aTokStm.GetToken_Next();
339 : }
340 : }
341 : else
342 0 : return sal_False;
343 103 : return sal_True;
344 : }
345 :
346 11185 : SvMetaType * SvIdlDataBase::FindType( const SvMetaType * pPType,
347 : SvMetaTypeMemberList & rList )
348 : {
349 1082370 : for( SvMetaTypeMemberList::const_iterator it = rList.begin(); it != rList.end(); ++it )
350 1080127 : if( *it == pPType )
351 8942 : return *it;
352 2243 : return NULL;
353 : }
354 :
355 2850 : SvMetaType * SvIdlDataBase::FindType( const rtl::OString& rName )
356 : {
357 42148 : for( SvMetaTypeMemberList::const_iterator it = aTypeList.begin(); it != aTypeList.end(); ++it )
358 42148 : if( rName.equals((*it)->GetName().getString()) )
359 2850 : return *it;
360 0 : return NULL;
361 : }
362 :
363 35927 : SvMetaType * SvIdlDataBase::ReadKnownType( SvTokenStream & rInStm )
364 : {
365 35927 : sal_Bool bIn = sal_False;
366 35927 : sal_Bool bOut = sal_False;
367 35927 : int nCall0 = CALL_VALUE;
368 35927 : int nCall1 = CALL_VALUE;
369 35927 : sal_Bool bSet = sal_False; // any attribute set
370 :
371 35927 : sal_uInt32 nTokPos = rInStm.Tell();
372 35927 : SvToken * pTok = rInStm.GetToken_Next();
373 :
374 35927 : 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 35927 : if( pTok->IsIdentifier() )
403 : {
404 30373 : rtl::OString aName = pTok->GetString();
405 30373 : SvMetaTypeMemberList & rList = GetTypeList();
406 30373 : SvMetaTypeMemberList::const_iterator it = rList.begin();
407 30373 : SvMetaType * pType = NULL;
408 2514831 : while( it != rList.end() )
409 : {
410 2476868 : if( (*it)->GetName().getString().equals(aName) )
411 : {
412 22783 : pType = *it;
413 22783 : break;
414 : }
415 2454085 : ++it;
416 : }
417 30373 : if( pType )
418 : {
419 22783 : pTok = rInStm.GetToken();
420 22783 : 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 22783 : if( !bSet )
439 : // is exactly this type
440 22783 : 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 30373 : }
453 : }
454 13144 : rInStm.Seek( nTokPos );
455 13144 : return NULL;
456 : }
457 :
458 12193 : 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 12193 : sal_uInt32 nTokPos = rInStm.Tell();
466 :
467 12193 : if( !pType )
468 12167 : pType = ReadKnownType( rInStm );
469 :
470 12193 : if( !pType )
471 : {
472 : // otherwise SlotId?
473 4130 : SvToken * pTok = rInStm.GetToken_Next();
474 4130 : if( pTok->IsIdentifier() )
475 : {
476 : sal_uLong n;
477 3795 : if( FindId( pTok->GetString(), &n ) )
478 : {
479 2707805 : for( sal_uLong i = 0; i < aAttrList.size(); i++ )
480 : {
481 2707805 : SvMetaAttribute * pAttr = aAttrList[i];
482 2707805 : if( pAttr->GetSlotId().getString().equals(pTok->GetString()) )
483 3795 : return pAttr;
484 : }
485 : }
486 :
487 0 : rtl::OStringBuffer aStr("Nicht gefunden : ");
488 0 : aStr.append(pTok->GetString());
489 0 : OSL_FAIL(aStr.getStr());
490 : }
491 : }
492 :
493 8398 : rInStm.Seek( nTokPos );
494 8398 : return NULL;
495 : }
496 :
497 8398 : SvMetaAttribute* SvIdlDataBase::SearchKnownAttr
498 : (
499 : const SvNumberIdentifier& rId
500 : )
501 : {
502 : sal_uLong n;
503 8398 : if( FindId( rId.getString(), &n ) )
504 : {
505 4368855 : for( sal_uLong i = 0; i < aAttrList.size(); i++ )
506 : {
507 4360859 : SvMetaAttribute * pAttr = aAttrList[i];
508 4360859 : if( pAttr->GetSlotId().getString() == rId.getString() )
509 41 : return pAttr;
510 : }
511 : }
512 :
513 8357 : return NULL;
514 : }
515 :
516 171 : SvMetaClass * SvIdlDataBase::ReadKnownClass( SvTokenStream & rInStm )
517 : {
518 171 : sal_uInt32 nTokPos = rInStm.Tell();
519 171 : SvToken * pTok = rInStm.GetToken_Next();
520 :
521 171 : if( pTok->IsIdentifier() )
522 3943 : for( sal_uLong n = 0; n < aClassList.size(); n++ )
523 : {
524 3943 : SvMetaClass * pClass = aClassList[n];
525 3943 : if( pClass->GetName().getString().equals(pTok->GetString()) )
526 171 : return pClass;
527 : }
528 :
529 0 : rInStm.Seek( nTokPos );
530 0 : return NULL;
531 : }
532 :
533 1646 : void SvIdlDataBase::Write(const rtl::OString& rText)
534 : {
535 1646 : if( nVerbosity != 0 )
536 0 : fprintf( stdout, "%s", rText.getStr() );
537 1646 : }
538 :
539 0 : void SvIdlDataBase::WriteError( const rtl::OString& rErrWrn,
540 : const rtl::OString& rFileName,
541 : const rtl::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 : rtl::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", rtl::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 : rtl::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 : DirEntry aFullName(rtl::OStringToOUString(pTok->GetString(), RTL_TEXTENCODING_ASCII_US));
638 0 : if( aFullName.Find( rPath ) )
639 : {
640 0 : this->AddDepFile(aFullName.GetFull());
641 : SvFileStream aStm( aFullName.GetFull(),
642 0 : STREAM_STD_READ | STREAM_NOCREATE );
643 0 : Load( aStm );
644 0 : if( aStm.GetError() != SVSTREAM_OK )
645 : {
646 0 : if( aStm.GetError() == SVSTREAM_WRONGVERSION )
647 : {
648 0 : rtl::OStringBuffer aStr("wrong version, file ");
649 : aStr.append(rtl::OUStringToOString(
650 0 : aFullName.GetFull(), RTL_TEXTENCODING_UTF8));
651 0 : SetError(aStr.makeStringAndClear(), pTok);
652 0 : WriteError( rInStm );
653 0 : bOk = sal_False;
654 : }
655 : else
656 : {
657 0 : aStm.Seek( 0 );
658 0 : aStm.ResetError();
659 0 : SvTokenStream aTokStm( aStm, aFullName.GetFull() );
660 0 : bOk = ReadSvIdl( aTokStm, sal_True, rPath );
661 : }
662 0 : }
663 : }
664 : else
665 0 : bOk = sal_False;
666 : }
667 : else
668 0 : bOk = sal_False;
669 : }
670 :
671 8 : sal_uInt32 nBeginPos = 0xFFFFFFFF; // can not happen with Tell
672 :
673 24 : while( bOk && nBeginPos != rInStm.Tell() )
674 : {
675 16 : nBeginPos = rInStm.Tell();
676 16 : pTok = rInStm.GetToken();
677 16 : if( pTok->IsEof() )
678 8 : return sal_True;
679 8 : if( pTok->IsEmpty() )
680 0 : bOk = sal_False;
681 :
682 : // only one import at the very beginning
683 8 : if( pTok->Is( SvHash_module() ) )
684 : {
685 8 : SvMetaModuleRef aModule = new SvMetaModule( rInStm.GetFileName(), bImported );
686 8 : if( aModule->ReadSvIdl( *this, rInStm ) )
687 8 : GetModuleList().push_back( aModule );
688 : else
689 0 : bOk = sal_False;
690 : }
691 : else
692 0 : bOk = sal_False;
693 : }
694 0 : if( !bOk || !pTok->IsEof() )
695 : {
696 : // error treatment
697 0 : WriteError( rInStm );
698 0 : return sal_False;
699 : }
700 0 : return sal_True;
701 : }
702 :
703 8 : sal_Bool SvIdlWorkingBase::WriteSvIdl( SvStream & rOutStm )
704 : {
705 8 : if( rOutStm.GetError() != SVSTREAM_OK )
706 0 : return sal_False;
707 :
708 8 : SvStringHashList aList;
709 8 : if( GetIdTable() )
710 : {
711 8 : GetIdTable()->FillHashList( &aList );
712 20339 : for ( size_t i = 0, n = aList.size(); i < n; ++i )
713 : {
714 20331 : SvStringHashEntry* pEntry = aList[ i ];
715 20331 : rOutStm << "#define " << pEntry->GetName().getStr()
716 20331 : << '\t'
717 : << rtl::OString::valueOf(static_cast<sal_Int64>(
718 60993 : pEntry->GetValue())).getStr()
719 20331 : << endl;
720 : }
721 : }
722 :
723 16 : for( sal_uLong n = 0; n < GetModuleList().size(); n++ )
724 : {
725 8 : SvMetaModule * pModule = GetModuleList()[n];
726 8 : pModule->WriteSvIdl( *this, rOutStm, 0 );
727 : }
728 8 : return sal_True;
729 : }
730 :
731 8 : sal_Bool SvIdlWorkingBase::WriteSfx( SvStream & rOutStm )
732 : {
733 8 : if( rOutStm.GetError() != SVSTREAM_OK )
734 0 : return sal_False;
735 :
736 : // reset all tmp variables for writing
737 8 : WriteReset();
738 8 : SvMemoryStream aTmpStm( 256000, 256000 );
739 : sal_uLong n;
740 16 : for( n = 0; n < GetModuleList().size(); n++ )
741 : {
742 8 : SvMetaModule * pModule = GetModuleList()[n];
743 8 : if( !pModule->IsImported() )
744 8 : pModule->WriteSfx( *this, aTmpStm );
745 8 : aTmpStm.Seek( 0 );
746 : }
747 2251 : for( n = 0; n < aUsedTypes.size(); n++ )
748 : {
749 2243 : SvMetaType * pType = aUsedTypes[n];
750 2243 : pType->WriteSfx( *this, rOutStm );
751 : }
752 8 : aUsedTypes.clear();
753 8 : rOutStm << aTmpStm;
754 8 : return sal_True;
755 : }
756 :
757 8 : sal_Bool SvIdlWorkingBase::WriteHelpIds( SvStream& rOutStm )
758 : {
759 8 : if( rOutStm.GetError() != SVSTREAM_OK )
760 0 : return sal_False;
761 :
762 8 : HelpIdTable aIdTable;
763 : sal_uLong n;
764 16 : for( n = 0; n < GetModuleList().size(); n++ )
765 : {
766 8 : SvMetaModule * pModule = GetModuleList()[n];
767 8 : pModule->WriteHelpIds( *this, rOutStm, aIdTable );
768 : }
769 :
770 8 : const SvMetaAttributeMemberList & rAttrList = GetAttrList();
771 8019 : for( n = 0; n < rAttrList.size(); n++ )
772 : {
773 8011 : SvMetaAttribute * pAttr = rAttrList[n];
774 8011 : pAttr->WriteHelpId( *this, rOutStm, aIdTable );
775 : }
776 :
777 8 : return sal_True;
778 : }
779 :
780 0 : sal_Bool SvIdlWorkingBase::WriteSfxItem( SvStream & )
781 : {
782 0 : return sal_False;
783 : }
784 :
785 133 : void SvIdlDataBase::StartNewFile( const String& rName )
786 : {
787 133 : bExport = ( aExportFile.EqualsIgnoreCaseAscii( rName ) );
788 133 : }
789 :
790 8011 : void SvIdlDataBase::AppendAttr( SvMetaAttribute *pAttr )
791 : {
792 8011 : aAttrList.push_back( pAttr );
793 8011 : if ( bExport )
794 1683 : pAttr->SetNewAttribute( sal_True );
795 8011 : }
796 :
797 0 : sal_Bool SvIdlWorkingBase::WriteCSV( SvStream& rStrm )
798 : {
799 0 : SvMetaAttributeMemberList &rList = GetAttrList();
800 0 : sal_uLong nCount = rList.size();
801 0 : for ( sal_uLong n=0; n<nCount; n++ )
802 : {
803 0 : if ( rList[n]->IsNewAttribute() )
804 : {
805 0 : rList[n]->WriteCSV( *this, rStrm );
806 : }
807 : }
808 :
809 0 : if ( rStrm.GetError() != SVSTREAM_OK )
810 0 : return sal_False;
811 : else
812 0 : return sal_True;
813 : }
814 :
815 0 : sal_Bool SvIdlWorkingBase::WriteDocumentation( SvStream & rOutStm )
816 : {
817 0 : if( rOutStm.GetError() != SVSTREAM_OK )
818 0 : return sal_False;
819 :
820 0 : for( sal_uLong n = 0; n < GetModuleList().size(); n++ )
821 : {
822 0 : SvMetaModule * pModule = GetModuleList()[n];
823 0 : if( !pModule->IsImported() )
824 0 : pModule->Write( *this, rOutStm, 0, WRITE_DOCU );
825 : }
826 0 : return sal_True;
827 : }
828 :
829 244 : void SvIdlDataBase::AddDepFile(String const& rFileName)
830 : {
831 244 : m_DepFiles.insert(rFileName);
832 244 : }
833 :
834 : #ifdef WNT
835 : static ::rtl::OString
836 : lcl_ConvertToCygwin(::rtl::OString const& rString)
837 : {
838 : sal_Int32 i = 0;
839 : sal_Int32 const len = rString.getLength();
840 : ::rtl::OStringBuffer buf(len + 16);
841 : if ((2 <= len) && (':' == rString[1]))
842 : {
843 : buf.append("/cygdrive/");
844 : buf.append(static_cast<sal_Char>(tolower(rString[0])));
845 : i = 2;
846 : }
847 : for (; i < len; ++i)
848 : {
849 : sal_Char const c(rString[i]);
850 : switch (c)
851 : {
852 : case '\\':
853 : buf.append('/');
854 : break;
855 : case ' ':
856 : buf.append("\\ ");
857 : break;
858 : default:
859 : buf.append(c);
860 : break;
861 : }
862 : }
863 : return buf.makeStringAndClear();
864 : }
865 : #endif
866 :
867 : static ::rtl::OString
868 252 : lcl_Convert(::rtl::OUString const& rString)
869 : {
870 : return
871 : #ifdef WNT
872 : lcl_ConvertToCygwin
873 : #endif
874 252 : (::rtl::OUStringToOString(rString, RTL_TEXTENCODING_UTF8));
875 : }
876 :
877 : struct WriteDep
878 : {
879 : SvFileStream & m_rStream;
880 8 : explicit WriteDep(SvFileStream & rStream) : m_rStream(rStream) { }
881 244 : void operator() (::rtl::OUString const& rItem)
882 : {
883 244 : m_rStream << " \\\n ";
884 244 : m_rStream << lcl_Convert(rItem).getStr();
885 244 : }
886 : };
887 :
888 8 : bool SvIdlDataBase::WriteDepFile(
889 : SvFileStream & rStream, ::rtl::OUString const& rTarget)
890 : {
891 8 : rStream << lcl_Convert(rTarget).getStr();
892 8 : rStream << " :";
893 8 : ::std::for_each(m_DepFiles.begin(), m_DepFiles.end(), WriteDep(rStream));
894 8 : return rStream.GetError() == SVSTREAM_OK;
895 : }
896 :
897 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|