xref: /aoo41x/main/idl/source/prj/database.cxx (revision 724893d4)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_idl.hxx"
26 
27 #include <ctype.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <tools/fsys.hxx>
31 #include <tools/debug.hxx>
32 #include <database.hxx>
33 #include <globals.hxx>
34 
35 /****************** SvIdlDataBase ****************************************/
36 /*************************************************************************
37 |*    SvIdlDataBase::SvIdlDataBase()
38 |*
39 |*    Beschreibung
40 *************************************************************************/
41 /*
42 void PrimeNumber(){
43     sal_uInt16 i, n;
44     for( i = 5001; i < 5500; i += 2 ){
45         for( n = 2; n < i && ((i % n) != 0); n++ );
46         if( n == i ){
47             printf( "\nPrimzahl: %d\n", i );
48             return;
49         }
50     }
51 }
52 */
53 
54 SvIdlDataBase::SvIdlDataBase( const SvCommand& rCmd )
55 	: bExport( sal_False )
56 	, nUniqueId( 0 )
57     , nVerbosity( rCmd.nVerbosity )
58     , bIsModified( sal_False )
59     , aPersStream( *IDLAPP->pClassMgr, NULL )
60     , pIdTable( NULL )
61 {
62 	//PrimeNumber();
63 }
64 
65 /*************************************************************************
66 |*    SvIdlDataBase::~SvIdlDataBase()
67 |*
68 |*    Beschreibung
69 *************************************************************************/
70 SvIdlDataBase::~SvIdlDataBase()
71 {
72     String * pStr = aIdFileList.First();
73     while( pStr )
74     {
75         delete pStr;
76         pStr = aIdFileList.Next();
77     }
78     delete pIdTable;
79 }
80 
81 /*************************************************************************
82 |*    SvIdlDataBase::GetTypeList()
83 |*
84 |*    Beschreibung
85 *************************************************************************/
86 #define ADD_TYPE( Name, OdlName, ParserChar, CName, BasName, BasPost )            \
87     aTypeList.Append( new SvMetaType( SvHash_##Name()->GetName(),	\
88                      BasName, OdlName, ParserChar, CName, BasName, BasPost ) );
89 
90 SvMetaTypeMemberList & SvIdlDataBase::GetTypeList()
91 {
92     if( aTypeList.Count() == 0 )
93     { // Initial fuellen
94         aTypeList.Append( new SvMetaTypeString() );
95         aTypeList.Append( new SvMetaTypevoid() );
96 
97 		// MI: IDispatch::Invoke kann keine unsigned
98         ADD_TYPE( UINT16,    "long", 'h', "unsigned short", "Long", "&" );
99         ADD_TYPE( INT16,     "short", 'h', "short", "Integer", "%" );
100         ADD_TYPE( UINT32,    "long", 'l', "unsigned long", "Long", "&" );
101         ADD_TYPE( INT32,     "long", 'l', "long", "Long", "&" );
102         ADD_TYPE( int,       "int", 'i', "int", "Integer", "%" );
103         ADD_TYPE( BOOL,      "boolean", 'b', "unsigned char", "Boolean", "" );
104         ADD_TYPE( char,      "char", 'c', "char", "Integer", "%" );
105         ADD_TYPE( BYTE,      "char", 'c', "unsigned char", "Integer", "%" );
106         ADD_TYPE( float,     "float", 'f', "float", "Single", "!" );
107         ADD_TYPE( double,    "double", 'F', "double", "Double", "#" );
108         ADD_TYPE( SbxObject, "VARIANT", 'o', "C_Object", "Object", "" );
109 
110 
111         // A c h t u n g !!!, bei hinzufuegen von Typen werden alle
112         // bin�ren Datenbasen inkompatibel
113 
114     /*
115         // So tun als ob die Init-Daten auf einem Stream gelesen wurden
116         SvMemoryStream aStm;
117         aPersStream.SetStream( &aStm );
118         // Alle Init-Daten Streamen
119         aPersStream << aTypeList;
120         // Nur die Id-Zuordnung merken
121         aPersStream.SetStream( NULL );
122     */
123     }
124     return aTypeList;
125 }
126 
127 /*************************************************************************
128 |*
129 |*    SvIdlDataBase::GetModuleInfo()
130 |*
131 |*    Beschreibung
132 |*    Ersterstellung    MM 13.12.94
133 |*    Letzte Aenderung  MM 13.12.94
134 |*
135 *************************************************************************/
136 SvMetaModule * SvIdlDataBase::GetModule( const ByteString & rName )
137 {
138     for( sal_uLong n = 0; n < aModuleList.Count(); n++ )
139         if( aModuleList.GetObject( n )->GetName() == rName )
140             return aModuleList.GetObject( n );
141     return NULL;
142 }
143 
144 /*************************************************************************
145 |*
146 |*    SvIdlDataBase::IsBinaryFormat()
147 |*
148 |*    Beschreibung
149 |*
150 *************************************************************************/
151 #define DATABASE_SIGNATURE  (sal_uInt32)0x13B799F2
152 #define DATABASE_VER 0x0006
153 sal_Bool SvIdlDataBase::IsBinaryFormat( SvStream & rStm )
154 {
155     sal_uInt32  nSig = 0;
156     sal_uLong   nPos = rStm.Tell();
157     rStm >> nSig;
158     rStm.Seek( nPos );
159 
160     return nSig == DATABASE_SIGNATURE;
161 }
162 
163 /*************************************************************************
164 |*
165 |*    SvIdlDataBase::Load()
166 |*
167 |*    Beschreibung
168 |*
169 *************************************************************************/
170 void SvIdlDataBase::Load( SvStream & rStm )
171 {
172     DBG_ASSERT( aTypeList.Count() == 0, "type list already initialized" );
173     SvPersistStream aPStm( *IDLAPP->pClassMgr, &rStm );
174 
175     sal_uInt16  nVersion = 0;
176     sal_uInt32  nSig = 0;
177 
178     aPStm >> nSig;
179     aPStm >> nVersion;
180     if( nSig != DATABASE_SIGNATURE )
181     {
182         aPStm.SetError( SVSTREAM_FILEFORMAT_ERROR );
183         return;
184     }
185     if( nVersion != DATABASE_VER )
186     {
187         aPStm.SetError( SVSTREAM_WRONGVERSION );
188         return;
189     }
190     aPStm >> aClassList;
191     aPStm >> aTypeList;
192     aPStm >> aAttrList;
193     aPStm >> aModuleList;
194     aPStm >> nUniqueId;
195 
196     if( aPStm.IsEof() )
197         aPStm.SetError( SVSTREAM_GENERALERROR );
198 }
199 
200 /*************************************************************************
201 |*    SvIdlDataBase::Save()
202 |*
203 |*    Beschreibung
204 *************************************************************************/
205 void SvIdlDataBase::Save( SvStream & rStm, sal_uInt32 nFlags )
206 {
207     SvPersistStream aPStm( *IDLAPP->pClassMgr, &rStm );
208     aPStm.SetContextFlags( nFlags );
209 
210     aPStm << (sal_uInt32)DATABASE_SIGNATURE;
211     aPStm << (sal_uInt16)DATABASE_VER;
212 
213     sal_Bool bOnlyStreamedObjs = sal_False;
214     if( nFlags & IDL_WRITE_CALLING )
215         bOnlyStreamedObjs = sal_True;
216 
217     if( bOnlyStreamedObjs )
218     {
219         SvMetaClassMemberList aList;
220         for( sal_uLong n = 0; n < GetModuleList().Count(); n++ )
221         {
222             SvMetaModule * pModule = GetModuleList().GetObject( n );
223             if( !pModule->IsImported() )
224                 aList.Append( pModule->GetClassList() );
225         }
226         aPStm << aList;
227     }
228     else
229         aPStm << aClassList;
230 
231     //aClassList.WriteObjects( aPStm, bOnlyStreamedObjs );
232     aTypeList.WriteObjects( aPStm, bOnlyStreamedObjs );
233     aAttrList.WriteObjects( aPStm, bOnlyStreamedObjs );
234     aModuleList.WriteObjects( aPStm, bOnlyStreamedObjs );
235 	aPStm << nUniqueId;
236 }
237 
238 /*************************************************************************
239 |*    SvIdlDataBase::SetError()
240 |*
241 |*    Beschreibung
242 *************************************************************************/
243 void SvIdlDataBase::SetError( const ByteString & rError, SvToken * pTok )
244 {
245 	if( pTok->GetLine() > 10000 )
246 		aError.SetText( "hgchcg" );
247 
248     if( aError.nLine < pTok->GetLine()
249       || (aError.nLine == pTok->GetLine() && aError.nColumn < pTok->GetColumn()) )
250     {
251         aError = SvIdlError( pTok->GetLine(), pTok->GetColumn() );
252         aError.SetText( rError );
253     }
254 }
255 
256 /*************************************************************************
257 |*    SvIdlDataBase::Push()
258 |*
259 |*    Beschreibung
260 *************************************************************************/
261 void SvIdlDataBase::Push( SvMetaObject * pObj )
262 {
263 	GetStack().Push( pObj );
264 }
265 
266 #ifdef IDL_COMPILER
267 /*************************************************************************
268 |*
269 |*    SvIdlDataBase::FindId()
270 |*
271 |*    Beschreibung
272 |*
273 *************************************************************************/
274 sal_Bool SvIdlDataBase::FindId( const ByteString & rIdName, sal_uLong * pVal )
275 {
276     if( pIdTable )
277     {
278         sal_uInt32 nHash;
279         if( pIdTable->Test( rIdName, &nHash ) )
280         {
281             *pVal = pIdTable->Get( nHash )->GetValue();
282             return sal_True;
283         }
284     }
285     return sal_False;
286 }
287 
288 /*************************************************************************
289 |*
290 |*    SvIdlDataBase::InsertId()
291 |*
292 |*    Beschreibung
293 |*
294 *************************************************************************/
295 sal_Bool SvIdlDataBase::InsertId( const ByteString & rIdName, sal_uLong nVal )
296 {
297     if( !pIdTable )
298         pIdTable = new SvStringHashTable( 20003 );
299 
300     sal_uInt32 nHash;
301     if( pIdTable->Insert( rIdName, &nHash ) )
302     {
303         pIdTable->Get( nHash )->SetValue( nVal );
304         return sal_True;
305     }
306     return sal_False;
307 }
308 
309 /*************************************************************************
310 |*    SvIdlDataBase::ReadIdFile()
311 |*
312 |*    Beschreibung
313 *************************************************************************/
314 sal_Bool SvIdlDataBase::ReadIdFile( const String & rFileName )
315 {
316     DirEntry aFullName( rFileName );
317     aFullName.Find( GetPath() );
318 
319     String * pIdFile = aIdFileList.First();
320     while( pIdFile )
321     {
322         if( *pIdFile == rFileName )
323             return sal_True; // schon eingelesen
324         pIdFile = aIdFileList.Next();
325     }
326 
327     aIdFileList.Insert( new String( rFileName ), LIST_APPEND );
328 
329     SvTokenStream aTokStm( aFullName.GetFull() );
330     if( aTokStm.GetStream().GetError() == SVSTREAM_OK )
331     {
332         SvToken * pTok = aTokStm.GetToken_Next();
333 
334         while( !pTok->IsEof() )
335         {
336             if( pTok->IsChar() && pTok->GetChar() == '#' )
337             {
338                 pTok = aTokStm.GetToken_Next();
339                 if( pTok->Is( SvHash_define() ) )
340                 {
341                     pTok = aTokStm.GetToken_Next();
342                     ByteString aDefName;
343                     if( pTok->IsIdentifier() )
344                         aDefName = pTok->GetString();
345                     else
346                     {
347                         ByteString aStr( "unexpected token after define" );
348                         // Fehler setzen
349                         SetError( aStr, pTok );
350                         WriteError( aTokStm );
351                         return sal_False;
352                     }
353 
354                     sal_uLong nVal = 0;
355                     sal_Bool bOk = sal_True;
356                     while( bOk )
357                     {
358                         pTok = aTokStm.GetToken_Next();
359                         if( pTok->IsIdentifier() )
360                         {
361                             sal_uLong n;
362                             if( FindId( pTok->GetString(), &n ) )
363                                 nVal += n;
364                             else
365                                 bOk = sal_False;
366                         }
367                         else if( pTok->IsChar() )
368                         {
369                             if( pTok->GetChar() == '-'
370                               || pTok->GetChar() == '/'
371                               || pTok->GetChar() == '*'
372                               || pTok->GetChar() == '&'
373                               || pTok->GetChar() == '|'
374                               || pTok->GetChar() == '^'
375                               || pTok->GetChar() == '~' )
376                             {
377                                 ByteString aStr( "unknown operator '" );
378                                 aStr += pTok->GetChar();
379                                 aStr += "'in define";
380                                 // Fehler setzen
381                                 SetError( aStr, pTok );
382                                 WriteError( aTokStm );
383                                 return sal_False;
384                             }
385                             if( pTok->GetChar() != '+'
386                               && pTok->GetChar() != '('
387                               && pTok->GetChar() != ')' )
388                                 // nur + erlaubt, Klammern spielen kein Rolle,
389                                 // da + komutativ ist
390                                 break;
391                         }
392                         else if( pTok->IsInteger() )
393                         {
394                             nVal += pTok->GetNumber();
395                         }
396                         else
397                             break;
398                     }
399                     if( bOk )
400                     {
401                         if( !InsertId( aDefName, nVal ) )
402                         {
403 	                        ByteString aStr = "hash table overflow: ";
404 			                SetError( aStr, pTok );
405                             WriteError( aTokStm );
406                             return sal_False;
407                         }
408                     }
409                 }
410                 else if( pTok->Is( SvHash_include() ) )
411                 {
412                     pTok = aTokStm.GetToken_Next();
413                     ByteString aName;
414                     if( pTok->IsString() )
415                         aName = pTok->GetString();
416                     else if( pTok->IsChar() && pTok->GetChar() == '<' )
417                     {
418                         pTok = aTokStm.GetToken_Next();
419                         while( !pTok->IsEof()
420                           && !(pTok->IsChar() && pTok->GetChar() == '>') )
421                         {
422                             aName += pTok->GetTokenAsString();
423                             pTok = aTokStm.GetToken_Next();
424                         }
425                         if( pTok->IsEof() )
426                         {
427                             ByteString aStr( "unexpected eof in #include" );
428                             // Fehler setzen
429                             SetError( aStr, pTok );
430                             WriteError( aTokStm );
431                             return sal_False;
432                         }
433                     }
434                     if( !ReadIdFile( String::CreateFromAscii(aName.GetBuffer()) ) )
435                     {
436                         ByteString aStr = "cannot read file: ";
437                         aStr += aName;
438                         SetError( aStr, pTok );
439                         WriteError( aTokStm );
440                         return sal_False;
441                     }
442                 }
443             }
444             else
445                 pTok = aTokStm.GetToken_Next();
446         }
447     }
448     else
449         return sal_False;
450     return sal_True;
451 }
452 
453 /*************************************************************************
454 |*    SvIdlDataBase::FindType()
455 |*
456 |*    Beschreibung
457 *************************************************************************/
458 SvMetaType * SvIdlDataBase::FindType( const SvMetaType * pPType,
459 									SvMetaTypeMemberList & rList )
460 {
461 	SvMetaType * pType = rList.First();
462 	while( pType && pPType != pType )
463 		pType = rList.Next();
464 	return pType;
465 }
466 
467 SvMetaType * SvIdlDataBase::FindType( const ByteString & rName )
468 {
469 	SvMetaType * pType = aTypeList.First();
470 	while( pType && rName != pType->GetName() )
471 		pType = aTypeList.Next();
472 	return pType;
473 }
474 
475 /*************************************************************************
476 |*    SvIdlDataBase::ReadKnownType()
477 |*
478 |*    Beschreibung
479 *************************************************************************/
480 SvMetaType * SvIdlDataBase::ReadKnownType( SvTokenStream & rInStm )
481 {
482     sal_Bool bIn	= sal_False;
483     sal_Bool bOut	= sal_False;
484     int nCall0	= CALL_VALUE;
485     int nCall1	= CALL_VALUE;
486 	sal_Bool bSet   = sal_False; //irgent ein Attribut gesetzt
487 
488     sal_uInt32  nTokPos = rInStm.Tell();
489     SvToken * pTok = rInStm.GetToken_Next();
490 
491 	if( pTok->HasHash() )
492 	{
493 	    sal_uInt32 nBeginPos = 0; // kann mit Tell nicht vorkommen
494 	    while( nBeginPos != rInStm.Tell() )
495 	    {
496 	        nBeginPos = rInStm.Tell();
497 	        if( pTok->Is( SvHash_in() ) )
498 	        {
499 	            bIn  = sal_True;
500 	            pTok = rInStm.GetToken_Next();
501 				bSet = sal_True;
502 	        }
503 	        if( pTok->Is( SvHash_out() ) )
504 	        {
505 	            bOut = sal_True;
506 	            pTok = rInStm.GetToken_Next();
507 				bSet = sal_True;
508 	        }
509 	        if( pTok->Is( SvHash_inout() ) )
510 	        {
511 	            bIn  = sal_True;
512 	            bOut = sal_True;
513 	            pTok = rInStm.GetToken_Next();
514 				bSet = sal_True;
515 	        }
516 	    }
517 	}
518 /*
519     SvMetaTypeList aTmpTypeList;
520     if( FillTypeList( aTmpTypeList, pTok ) )
521 */
522     if( pTok->IsIdentifier() )
523     {
524         ByteString aName = pTok->GetString();
525         SvMetaTypeMemberList & rList = GetTypeList();
526         SvMetaType * pType = rList.First();
527         while( pType )
528         {
529             if( pType->GetName() == aName )
530 				break;
531             pType = rList.Next();
532         }
533 		if( pType )
534 		{
535 			pTok = rInStm.GetToken();
536 			if( pTok->IsChar() )
537 			{
538 				if( pTok->GetChar() == '&' || pTok->GetChar() == '*' )
539 				{
540 					nCall0 = (pTok->GetChar() == '&') ? CALL_REFERENCE :
541 														CALL_POINTER;
542 					rInStm.GetToken_Next();
543 					pTok = rInStm.GetToken();
544 					if( pTok->GetChar() == '&' || pTok->GetChar() == '*' )
545 					{
546 						nCall1 = (pTok->GetChar() == '&') ? CALL_REFERENCE :
547 															CALL_POINTER;
548 						rInStm.GetToken_Next();
549 					}
550 					bSet = sal_True;
551 				}
552 			}
553 			/*
554 			SvMetaType * pMetaType = aTmpTypeList.First();
555 			while( pMetaType )
556 			{
557 				if( pMetaType->GetIn() == bIn
558 				  && pMetaType->GetOut() == bOut
559 				  && pMetaType->GetCall0() == nCall0
560 				  && pMetaType->GetCall1() == nCall1 )
561 				{
562 					return pMetaType;
563 				}
564 				pMetaType = aTmpTypeList.Next();
565 			}
566 			*/
567 			//SvMetaType * pType = aTmpTypeList.First();
568 			if( !bSet )
569 				// Ist genau dieser Typ
570 				return pType;
571 
572 			DBG_ASSERT( aTmpTypeList.First(), "mindestens ein Element" );
573 			SvMetaTypeRef xType = new SvMetaType( pType->GetName(), 'h', "dummy" );
574 			xType->SetRef( pType );
575 			xType->SetIn( bIn );
576 			xType->SetOut( bOut );
577 			xType->SetCall0( nCall0 );
578 			xType->SetCall1( nCall1 );
579 
580 			aTmpTypeList.Append( xType );
581 			return xType;
582 		}
583     }
584     rInStm.Seek( nTokPos );
585     return NULL;
586 }
587 
588 /*************************************************************************
589 |*
590 |*    SvIdlDataBase::ReadKnownAttr()
591 |*
592 |*    Beschreibung
593 |*
594 *************************************************************************/
595 SvMetaAttribute * SvIdlDataBase::ReadKnownAttr
596 (
597 	SvTokenStream & rInStm,
598 	SvMetaType *	pType	/* Wenn der pType == NULL, dann muss der Typ
599 							   noch gelesen werden. */
600 )
601 {
602     sal_uInt32  nTokPos = rInStm.Tell();
603 
604 	if( !pType )
605     	pType = ReadKnownType( rInStm );
606 
607     if( pType )
608     {
609 		// Wenn wir Slots auf die Wiese stellen, d"urfen wir nicht voraussetzen,
610 		// da\s jeder Slot einen anderen Namen hat!
611 /*
612         SvToken * pTok = rInStm.GetToken_Next();
613         if( pTok->IsIdentifier() )
614             for( sal_uLong n = 0; n < aAttrList.Count(); n++ )
615             {
616                 SvMetaAttribute * pAttr = aAttrList.GetObject( n );
617                 if( pAttr->GetName() == pTok->GetString() )
618                     return pAttr;
619             }
620 */
621     }
622     else
623     {
624         // sonst SlotId?
625         SvToken * pTok = rInStm.GetToken_Next();
626 	    if( pTok->IsIdentifier() )
627 	    {
628 			sal_uLong n;
629 	        if( FindId( pTok->GetString(), &n ) )
630 	        {
631 	            for( sal_uLong i = 0; i < aAttrList.Count(); i++ )
632 	            {
633 	                SvMetaAttribute * pAttr = aAttrList.GetObject( i );
634 	                if( pAttr->GetSlotId() == pTok->GetString() )
635 	                    return pAttr;
636 	            }
637 	        }
638 
639 			ByteString aStr( "Nicht gefunden : " );
640 			aStr += pTok->GetString();
641             DBG_ERROR( aStr.GetBuffer() );
642 		}
643     }
644 
645     rInStm.Seek( nTokPos );
646     return NULL;
647 }
648 
649 SvMetaAttribute* SvIdlDataBase::SearchKnownAttr
650 (
651 	const SvNumberIdentifier& rId
652 )
653 {
654 	sal_uLong n;
655 	if( FindId( rId, &n ) )
656 	{
657 	    for( sal_uLong i = 0; i < aAttrList.Count(); i++ )
658 	    {
659 	        SvMetaAttribute * pAttr = aAttrList.GetObject( i );
660 	        if( pAttr->GetSlotId() == rId )
661 	            return pAttr;
662 	    }
663 	}
664 
665 	return NULL;
666 }
667 
668 /*************************************************************************
669 |*    SvIdlDataBase::ReadKnownClass()
670 |*
671 |*    Beschreibung
672 *************************************************************************/
673 SvMetaClass * SvIdlDataBase::ReadKnownClass( SvTokenStream & rInStm )
674 {
675     sal_uInt32  nTokPos = rInStm.Tell();
676     SvToken * pTok = rInStm.GetToken_Next();
677 
678     if( pTok->IsIdentifier() )
679         for( sal_uLong n = 0; n < aClassList.Count(); n++ )
680         {
681             SvMetaClass * pClass = aClassList.GetObject( n );
682             if( pClass->GetName() == pTok->GetString() )
683                 return pClass;
684         }
685 
686     rInStm.Seek( nTokPos );
687     return NULL;
688 }
689 
690 /*************************************************************************
691 |*    SvIdlDataBase::Write()
692 |*
693 |*    Beschreibung
694 *************************************************************************/
695 void SvIdlDataBase::Write( const ByteString & rText )
696 {
697     if( nVerbosity != 0 )
698         fprintf( stdout, "%s", rText.GetBuffer() );
699 }
700 
701 /*************************************************************************
702 |*    SvIdlDataBase::WriteError()
703 |*
704 |*    Beschreibung
705 *************************************************************************/
706 void SvIdlDataBase::WriteError( const ByteString & rErrWrn,
707 								const ByteString & rFileName,
708 								const ByteString & rErrorText,
709 								sal_uLong nRow, sal_uLong nColumn ) const
710 {
711     //Fehlerbehandlung
712     fprintf( stderr, "\n%s --- %s: ( %ld, %ld )\n",
713              rFileName.GetBuffer(), rErrWrn.GetBuffer(), nRow, nColumn );
714 
715     if( rErrorText.Len() )
716     { // Fehler gesetzt
717         fprintf( stderr, "\t%s\n", rErrorText.GetBuffer() );
718 	}
719 }
720 
721 /*************************************************************************
722 |*    SvIdlDataBase::WriteError()
723 |*
724 |*    Beschreibung
725 *************************************************************************/
726 void SvIdlDataBase::WriteError( SvTokenStream & rInStm )
727 {
728     //Fehlerbehandlung
729     String aFileName( rInStm.GetFileName() );
730 	ByteString aErrorText;
731 	sal_uLong	nRow = 0, nColumn = 0;
732 
733     rInStm.SeekEnd();
734     SvToken *pTok = rInStm.GetToken();
735 
736     // Fehlerposition
737 	nRow 	= pTok->GetLine();
738 	nColumn = pTok->GetColumn();
739 
740     if( aError.IsError() )
741     { // Fehler gesetzt
742         // Fehler Token suchen
743 	    // Fehlertext
744 		if( aError.GetText().Len() )
745 		{
746 			aErrorText = "may be <";
747         	aErrorText += aError.GetText();
748 		}
749 		SvToken * pPrevTok = NULL;
750         while( pTok != pPrevTok )
751         {
752 			pPrevTok = pTok;
753             if( pTok->GetLine() == aError.nLine
754               && pTok->GetColumn() == aError.nColumn )
755                 break;
756             pTok = rInStm.GetToken_PrevAll();
757         }
758 
759         // Fehlerposition
760 		aErrorText += "> at ( ";
761 		aErrorText += ByteString::CreateFromInt64(aError.nLine);
762 		aErrorText += ", ";
763 		aErrorText += ByteString::CreateFromInt64(aError.nColumn);
764 		aErrorText += " )";
765 
766 		// Fehler zuruecksetzen
767 		aError = SvIdlError();
768     }
769 
770     WriteError( "error", ByteString( aFileName, RTL_TEXTENCODING_UTF8 ), aErrorText, nRow, nColumn );
771 
772     DBG_ASSERT( pTok, "token must be found" );
773     if( !pTok )
774         return;
775 
776     // Identifier in der Naehe suchen
777     if( !pTok->IsIdentifier() )
778     {
779         rInStm.GetToken_PrevAll();
780         pTok = rInStm.GetToken();
781     }
782     if( pTok && pTok->IsIdentifier() )
783     {
784         ByteString aN = IDLAPP->pHashTable->GetNearString( pTok->GetString() );
785         if( aN.Len() )
786             fprintf( stderr, "%s versus %s\n", pTok->GetString().GetBuffer(), aN.GetBuffer() );
787     }
788 }
789 
790 /****************** SvIdlWorkingBase ****************************************/
791 /*************************************************************************
792 |*    SvIdlWorkingBase::SvIdlWorkingBase()
793 |*
794 |*    Beschreibung
795 *************************************************************************/
796 SvIdlWorkingBase::SvIdlWorkingBase(const SvCommand& rCmd) : SvIdlDataBase(rCmd)
797 {
798 }
799 
800 /*************************************************************************
801 |*    SvIdlWorkingBase::ReadSvIdl()
802 |*
803 |*    Beschreibung
804 *************************************************************************/
805 sal_Bool SvIdlWorkingBase::ReadSvIdl( SvTokenStream & rInStm, sal_Bool bImported, const String & rPath )
806 {
807     aPath = rPath; // nur fuer den durchlauf gueltig
808     SvToken * pTok;
809     sal_Bool bOk = sal_True;
810         pTok = rInStm.GetToken();
811         // nur ein import ganz am Anfang
812         if( pTok->Is( SvHash_import() ) )
813         {
814             rInStm.GetToken_Next();
815             rInStm.Read( '(' ); // optional
816             pTok = rInStm.GetToken_Next();
817             if( pTok->IsString() )
818             {
819                 DirEntry aFullName( String::CreateFromAscii( pTok->GetString().GetBuffer() ) );
820                 if( aFullName.Find( rPath ) )
821                 {
822                     SvFileStream aStm( aFullName.GetFull(),
823                                         STREAM_STD_READ | STREAM_NOCREATE );
824                     Load( aStm );
825                     if( aStm.GetError() != SVSTREAM_OK )
826                     {
827                         if( aStm.GetError() == SVSTREAM_WRONGVERSION )
828                         {
829                             ByteString aStr( "wrong version, file " );
830                             aStr += ByteString( aFullName.GetFull(), RTL_TEXTENCODING_UTF8 );
831                             SetError( aStr, pTok );
832                             WriteError( rInStm );
833                             bOk = sal_False;
834                         }
835                         else
836                         {
837                             aStm.Seek( 0 );
838                             aStm.ResetError();
839                             SvTokenStream aTokStm( aStm, aFullName.GetFull() );
840                             bOk = ReadSvIdl( aTokStm, sal_True, rPath );
841                         }
842                     }
843                 }
844                 else
845                     bOk = sal_False;
846             }
847             else
848                 bOk = sal_False;
849         }
850 
851     sal_uInt32 nBeginPos = 0xFFFFFFFF; // kann mit Tell nicht vorkommen
852 
853     while( bOk && nBeginPos != rInStm.Tell() )
854     {
855         nBeginPos = rInStm.Tell();
856         pTok = rInStm.GetToken();
857         if( pTok->IsEof() )
858             return sal_True;
859         if( pTok->IsEmpty() )
860             bOk = sal_False;
861 
862         // nur ein import ganz am Anfang
863         /*else */if( pTok->Is( SvHash_module() ) )
864         {
865             SvMetaModuleRef aModule = new SvMetaModule( rInStm.GetFileName(), bImported );
866             if( aModule->ReadSvIdl( *this, rInStm ) )
867                 GetModuleList().Append( aModule );
868             else
869                 bOk = sal_False;
870         }
871         else
872             bOk = sal_False;
873     }
874     if( !bOk || !pTok->IsEof() )
875     {
876          //Fehlerbehandlung
877          WriteError( rInStm );
878          return sal_False;
879     }
880     return sal_True;
881 }
882 
883 /*************************************************************************
884 |*    SvIdlWorkingBase::WriteSvIdl()
885 |*
886 |*    Beschreibung
887 *************************************************************************/
888 sal_Bool SvIdlWorkingBase::WriteSvIdl( SvStream & rOutStm )
889 {
890     if( rOutStm.GetError() != SVSTREAM_OK )
891         return sal_False;
892 
893     SvStringHashList aList;
894     if( GetIdTable() )
895     {
896         GetIdTable()->FillHashList( &aList );
897         SvStringHashEntry * pEntry = aList.First();
898         while( pEntry )
899         {
900             rOutStm << "#define " << pEntry->GetName().GetBuffer()
901                     << '\t'
902                     << ByteString::CreateFromInt64(
903                         pEntry->GetValue() ).GetBuffer()
904                     << endl;
905             pEntry = aList.Next();
906         }
907     }
908 
909     for( sal_uLong n = 0; n < GetModuleList().Count(); n++ )
910     {
911         SvMetaModule * pModule = GetModuleList().GetObject( n );
912         //if( !pModule->IsImported() )
913             pModule->WriteSvIdl( *this, rOutStm, 0 );
914     }
915     return sal_True;
916 }
917 
918 /*************************************************************************
919 |*    SvIdlWorkingBase::WriteSfx()
920 |*
921 |*    Beschreibung
922 *************************************************************************/
923 sal_Bool SvIdlWorkingBase::WriteSfx( SvStream & rOutStm )
924 {
925     if( rOutStm.GetError() != SVSTREAM_OK )
926         return sal_False;
927 
928 	// alle Tmp-Variablen fuer das Schreiben zuruecksetzen
929 	WriteReset();
930 	SvMemoryStream aTmpStm( 256000, 256000 );
931 	sal_uLong n;
932     for( n = 0; n < GetModuleList().Count(); n++ )
933     {
934         SvMetaModule * pModule = GetModuleList().GetObject( n );
935         if( !pModule->IsImported() )
936             pModule->WriteSfx( *this, aTmpStm );
937 		aTmpStm.Seek( 0 );
938     }
939     for( n = 0; n < aUsedTypes.Count(); n++ )
940     {
941         SvMetaType * pType = aUsedTypes.GetObject( n );
942         pType->WriteSfx( *this, rOutStm );
943     }
944 	aUsedTypes.Clear();
945 	rOutStm << aTmpStm;
946     return sal_True;
947 }
948 
949 sal_Bool SvIdlWorkingBase::WriteHelpIds( SvStream& rOutStm )
950 {
951     if( rOutStm.GetError() != SVSTREAM_OK )
952         return sal_False;
953 
954     Table aIdTable;
955 	sal_uLong n;
956     for( n = 0; n < GetModuleList().Count(); n++ )
957     {
958         SvMetaModule * pModule = GetModuleList().GetObject( n );
959         //if( !pModule->IsImported() )
960             pModule->WriteHelpIds( *this, rOutStm, &aIdTable );
961     }
962 
963     const SvMetaAttributeMemberList & rAttrList = GetAttrList();
964     for( n = 0; n < rAttrList.Count(); n++ )
965     {
966         SvMetaAttribute * pAttr = rAttrList.GetObject( n );
967         pAttr->WriteHelpId( *this, rOutStm, &aIdTable );
968     }
969 
970 	return sal_True;
971 }
972 
973 /*************************************************************************
974 |*    SvIdlWorkingBase::WriteSfxItem()
975 |*
976 |*    Beschreibung
977 *************************************************************************/
978 sal_Bool SvIdlWorkingBase::WriteSfxItem( SvStream & )
979 {
980 	return sal_False;
981 }
982 
983 void SvIdlDataBase::StartNewFile( const String& rName )
984 {
985     bExport = ( aExportFile.EqualsIgnoreCaseAscii( rName ) );
986 }
987 
988 void SvIdlDataBase::AppendAttr( SvMetaAttribute *pAttr )
989 {
990 	aAttrList.Append( pAttr );
991 	if ( bExport )
992 		pAttr->SetNewAttribute( sal_True );
993 }
994 
995 sal_Bool SvIdlWorkingBase::WriteCSV( SvStream& rStrm )
996 {
997 	SvMetaAttributeMemberList &rList = GetAttrList();
998 	sal_uLong nCount = rList.Count();
999 	for ( sal_uLong n=0; n<nCount; n++ )
1000 	{
1001 		if ( rList.GetObject(n)->IsNewAttribute() )
1002 		{
1003 			rList.GetObject(n)->WriteCSV( *this, rStrm );
1004 		}
1005 	}
1006 
1007 	if ( rStrm.GetError() != SVSTREAM_OK )
1008 		return sal_False;
1009 	else
1010 		return sal_True;
1011 }
1012 
1013 /*************************************************************************
1014 |*    SvIdlWorkingBase::WriteDocumentation()
1015 |*
1016 |*    Beschreibung
1017 *************************************************************************/
1018 sal_Bool SvIdlWorkingBase::WriteDocumentation( SvStream & rOutStm )
1019 {
1020     if( rOutStm.GetError() != SVSTREAM_OK )
1021         return sal_False;
1022 
1023     for( sal_uLong n = 0; n < GetModuleList().Count(); n++ )
1024     {
1025         SvMetaModule * pModule = GetModuleList().GetObject( n );
1026         if( !pModule->IsImported() )
1027             pModule->Write( *this, rOutStm, 0, WRITE_DOCU );
1028     }
1029     return sal_True;
1030 }
1031 
1032 
1033 
1034 #endif // IDL_COMPILER
1035 
1036