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 :
24 : #include <rtl/strbuf.hxx>
25 : #include <osl/diagnose.h>
26 :
27 : #include <object.hxx>
28 : #include <globals.hxx>
29 : #include <database.hxx>
30 :
31 0 : TYPEINIT1( SvClassElement, SvPersistBase );
32 :
33 112 : SvClassElement::SvClassElement()
34 : {
35 112 : };
36 :
37 0 : TYPEINIT1( SvMetaClass, SvMetaType );
38 190 : SvMetaClass::SvMetaClass()
39 190 : : aAutomation( true, false )
40 : {
41 190 : }
42 :
43 184 : void SvMetaClass::ReadAttributesSvIdl( SvIdlDataBase & rBase,
44 : SvTokenStream & rInStm )
45 : {
46 184 : SvMetaType::ReadAttributesSvIdl( rBase, rInStm );
47 184 : aAutomation.ReadSvIdl( SvHash_Automation(), rInStm );
48 184 : }
49 :
50 4414 : void SvMetaClass::ReadContextSvIdl( SvIdlDataBase & rBase,
51 : SvTokenStream & rInStm )
52 : {
53 4414 : sal_uInt32 nTokPos = rInStm.Tell();
54 4414 : SvToken * pTok = rInStm.GetToken_Next();
55 :
56 4414 : if( pTok->Is( SvHash_import() ) )
57 : {
58 112 : SvMetaClass * pClass = rBase.ReadKnownClass( rInStm );
59 112 : if( pClass )
60 : {
61 112 : SvClassElementRef xEle = new SvClassElement();
62 112 : xEle->SetClass( pClass );
63 112 : aClassList.push_back( xEle );
64 :
65 112 : if( rInStm.Read( '[' ) )
66 : {
67 59 : pTok = rInStm.GetToken_Next();
68 59 : if( pTok->Is( SvHash_Automation() ) )
69 : {
70 59 : if( rInStm.Read( ']' ) )
71 : {
72 59 : if( xAutomationInterface.Is() )
73 : {
74 : // set error
75 : rBase.SetError( "Automation already set",
76 0 : rInStm.GetToken() );
77 0 : rBase.WriteError( rInStm );
78 : }
79 59 : xAutomationInterface = pClass;
80 59 : xEle->SetAutomation( true );
81 : }
82 : else
83 : {
84 : // set error
85 0 : rBase.SetError( "missing ]", rInStm.GetToken() );
86 0 : rBase.WriteError( rInStm );
87 : }
88 : }
89 : else
90 : {
91 : // set error
92 : rBase.SetError( "only attribute Automation allowed",
93 0 : rInStm.GetToken() );
94 0 : rBase.WriteError( rInStm );
95 : }
96 : }
97 112 : pTok = rInStm.GetToken();
98 112 : if( pTok->IsString() )
99 : {
100 7 : xEle->SetPrefix( pTok->GetString() );
101 7 : rInStm.GetToken_Next();
102 : }
103 112 : return;
104 : }
105 : else
106 : {
107 : // set error
108 0 : rBase.SetError( "unknown imported interface", rInStm.GetToken() );
109 0 : rBase.WriteError( rInStm );
110 : }
111 : }
112 : else
113 : {
114 4302 : rInStm.Seek( nTokPos );
115 4302 : SvMetaType * pType = rBase.ReadKnownType( rInStm );
116 :
117 4302 : bool bOk = false;
118 4302 : SvMetaAttributeRef xAttr;
119 4302 : if( !pType || pType->IsItem() )
120 : {
121 4286 : xAttr = new SvMetaSlot( pType );
122 4286 : if( xAttr->ReadSvIdl( rBase, rInStm ) )
123 4096 : bOk = xAttr->Test( rBase, rInStm );
124 : }
125 : else
126 : {
127 16 : xAttr = new SvMetaAttribute( pType );
128 16 : if( xAttr->ReadSvIdl( rBase, rInStm ) )
129 16 : bOk = xAttr->Test( rBase, rInStm );
130 : }
131 :
132 4302 : if( bOk )
133 4112 : bOk = TestAttribute( rBase, rInStm, *xAttr );
134 4302 : if( bOk )
135 : {
136 4112 : if( !xAttr->GetSlotId().IsSet() )
137 : {
138 5 : SvNumberIdentifier aI;
139 5 : aI.SetValue( rBase.GetUniqueId() );
140 5 : xAttr->SetSlotId( aI );
141 : }
142 4112 : aAttrList.push_back( xAttr );
143 4112 : return;
144 190 : }
145 : }
146 190 : rInStm.Seek( nTokPos );
147 : }
148 :
149 190 : bool SvMetaClass::ReadSvIdl( SvIdlDataBase & rBase, SvTokenStream & rInStm )
150 : {
151 190 : sal_uLong nTokPos = rInStm.Tell();
152 190 : if( SvMetaType::ReadHeaderSvIdl( rBase, rInStm ) && GetType() == TYPE_CLASS )
153 : {
154 190 : bool bOk = true;
155 190 : if( rInStm.Read( ':' ) )
156 : {
157 59 : aSuperClass = rBase.ReadKnownClass( rInStm );
158 59 : bOk = aSuperClass.Is();
159 59 : if( !bOk )
160 : {
161 : // set error
162 : rBase.SetError( "unknown super class",
163 0 : rInStm.GetToken() );
164 0 : rBase.WriteError( rInStm );
165 : }
166 : }
167 190 : if( bOk )
168 : {
169 190 : rBase.Write(OString('.'));
170 190 : bOk = SvMetaName::ReadSvIdl( rBase, rInStm );
171 : }
172 190 : if( bOk )
173 190 : return bOk;
174 : }
175 0 : rInStm.Seek( nTokPos );
176 0 : return false;
177 : }
178 :
179 4487 : bool SvMetaClass::TestAttribute( SvIdlDataBase & rBase, SvTokenStream & rInStm,
180 : SvMetaAttribute & rAttr ) const
181 : {
182 4487 : if ( !rAttr.GetRef() && rAttr.IsA( TYPE( SvMetaSlot ) ) )
183 : {
184 : OSL_FAIL( "Neuer Slot : " );
185 : OSL_FAIL( rAttr.GetSlotId().getString().getStr() );
186 : }
187 :
188 453161 : for( sal_uLong n = 0; n < aAttrList.size(); n++ )
189 : {
190 448674 : SvMetaAttribute * pS = aAttrList[n];
191 448674 : if( pS->GetName().getString() == rAttr.GetName().getString() )
192 : {
193 : // values have to match
194 10 : if( pS->GetSlotId().GetValue() != rAttr.GetSlotId().GetValue() )
195 : {
196 : OSL_FAIL( "Same Name in MetaClass : " );
197 : OSL_FAIL( pS->GetName().getString().getStr() );
198 : OSL_FAIL( pS->GetSlotId().getString().getStr() );
199 : OSL_FAIL( rAttr.GetSlotId().getString().getStr() );
200 :
201 0 : OStringBuffer aStr("Attribute's ");
202 0 : aStr.append(pS->GetName().getString());
203 0 : aStr.append(" with different id's");
204 0 : rBase.SetError(aStr.makeStringAndClear(), rInStm.GetToken());
205 0 : rBase.WriteError( rInStm );
206 0 : return false;
207 : }
208 : }
209 : else
210 : {
211 448664 : sal_uInt32 nId1 = pS->GetSlotId().GetValue();
212 448664 : sal_uInt32 nId2 = rAttr.GetSlotId().GetValue();
213 448664 : if( nId1 == nId2 && nId1 != 0 )
214 : {
215 : OSL_FAIL( "Gleiche Id in MetaClass : " );
216 : OSL_FAIL(OString::number(pS->GetSlotId().GetValue()).getStr());
217 : OSL_FAIL( pS->GetSlotId().getString().getStr() );
218 : OSL_FAIL( rAttr.GetSlotId().getString().getStr() );
219 :
220 0 : OStringBuffer aStr("Attribute ");
221 0 : aStr.append(pS->GetName().getString());
222 0 : aStr.append(" and Attribute ");
223 0 : aStr.append(rAttr.GetName().getString());
224 0 : aStr.append(" with equal id's");
225 0 : rBase.SetError(aStr.makeStringAndClear(), rInStm.GetToken());
226 0 : rBase.WriteError( rInStm );
227 0 : return false;
228 : }
229 : }
230 : }
231 4487 : SvMetaClass * pSC = aSuperClass;
232 4487 : if( pSC )
233 375 : return pSC->TestAttribute( rBase, rInStm, rAttr );
234 4112 : return true;
235 : }
236 :
237 83 : sal_uInt16 SvMetaClass::WriteSlotParamArray( SvIdlDataBase & rBase,
238 : SvSlotElementList & rSlotList,
239 : SvStream & rOutStm )
240 : {
241 83 : sal_uInt16 nCount = 0;
242 6034 : for ( size_t i = 0, n = rSlotList.size(); i < n; ++i )
243 : {
244 5951 : SvSlotElement *pEle = rSlotList[ i ];
245 5951 : SvMetaSlot *pAttr = pEle->xSlot;
246 5951 : nCount = nCount + pAttr->WriteSlotParamArray( rBase, rOutStm );
247 : }
248 :
249 83 : return nCount;
250 : }
251 :
252 83 : sal_uInt16 SvMetaClass::WriteSlots( const OString& rShellName,
253 : sal_uInt16 nCount, SvSlotElementList & rSlotList,
254 : SvIdlDataBase & rBase,
255 : SvStream & rOutStm )
256 : {
257 83 : sal_uInt16 nSCount = 0;
258 6034 : for ( size_t i = 0, n = rSlotList.size(); i < n; ++i )
259 : {
260 5951 : SvSlotElement * pEle = rSlotList[ i ];
261 5951 : SvMetaSlot * pAttr = pEle->xSlot;
262 : nSCount = nSCount + pAttr->WriteSlotMap( rShellName, nCount + nSCount,
263 : rSlotList, i, rBase,
264 5951 : rOutStm );
265 : }
266 :
267 83 : return nSCount;
268 : }
269 :
270 211 : void SvMetaClass::InsertSlots( SvSlotElementList& rList, std::vector<sal_uLong>& rSuperList,
271 : SvMetaClassList &rClassList,
272 : const OString& rPrefix, SvIdlDataBase& rBase)
273 : {
274 : // was this class already written?
275 574 : for ( size_t i = 0, n = rClassList.size(); i < n ; ++i )
276 380 : if ( rClassList[ i ] == this )
277 228 : return;
278 :
279 194 : rClassList.push_back( this );
280 :
281 : // write all direct attributes
282 : sal_uLong n;
283 6105 : for( n = 0; n < aAttrList.size(); n++ )
284 : {
285 5911 : SvMetaAttribute * pAttr = aAttrList[n];
286 :
287 5911 : sal_uLong nId = pAttr->GetSlotId().GetValue();
288 :
289 : std::vector<sal_uLong>::iterator iter = std::find(rSuperList.begin(),
290 5911 : rSuperList.end(),nId);
291 :
292 5911 : if( iter == rSuperList.end() )
293 : {
294 : // Write only if not already written by subclass or
295 : // imported interface.
296 5892 : rSuperList.push_back(nId);
297 5892 : pAttr->Insert(rList, rPrefix, rBase);
298 : }
299 : }
300 :
301 : // All Interfaces already imported by SuperShells should not be
302 : // written any more.
303 : // It is prohibited that Shell and SuperShell directly import the same
304 : //class.
305 194 : if( IsShell() && aSuperClass.Is() )
306 27 : aSuperClass->FillClasses( rClassList );
307 :
308 : // Write all attributes of the imported classes, as long as they have
309 : // not already been imported by the superclass.
310 288 : for( n = 0; n < aClassList.size(); n++ )
311 : {
312 94 : SvClassElement * pEle = aClassList[n];
313 94 : SvMetaClass * pCl = pEle->GetClass();
314 94 : OStringBuffer rPre(rPrefix);
315 94 : if( !rPre.isEmpty() && !pEle->GetPrefix().isEmpty() )
316 0 : rPre.append('.');
317 94 : rPre.append(pEle->GetPrefix());
318 :
319 : // first of all write direct imported interfaces
320 : pCl->InsertSlots( rList, rSuperList, rClassList,
321 94 : rPre.makeStringAndClear(), rBase );
322 94 : }
323 :
324 : // only write superclass if no shell and not in the list
325 194 : if( !IsShell() && aSuperClass.Is() )
326 : {
327 34 : aSuperClass->InsertSlots( rList, rSuperList, rClassList, rPrefix, rBase );
328 : }
329 : }
330 :
331 99 : void SvMetaClass::FillClasses( SvMetaClassList & rList )
332 : {
333 : // Am I not yet in?
334 357 : for ( size_t i = 0, n = rList.size(); i < n; ++i )
335 263 : if ( rList[ i ] == this )
336 104 : return;
337 :
338 94 : rList.push_back( this );
339 :
340 : // my imports
341 135 : for( size_t n = 0; n < aClassList.size(); n++ )
342 : {
343 41 : SvClassElement * pEle = aClassList[n];
344 41 : SvMetaClass * pCl = pEle->GetClass();
345 41 : pCl->FillClasses( rList );
346 : }
347 :
348 : // my superclass
349 94 : if( aSuperClass.Is() )
350 31 : aSuperClass->FillClasses( rList );
351 : }
352 :
353 :
354 83 : void SvMetaClass::WriteSlotStubs( const OString& rShellName,
355 : SvSlotElementList & rSlotList,
356 : ByteStringList & rList,
357 : SvStream & rOutStm )
358 : {
359 : // write all attributes
360 6034 : for ( size_t i = 0, n = rSlotList.size(); i < n; ++i )
361 : {
362 5951 : SvSlotElement *pEle = rSlotList[ i ];
363 5951 : SvMetaSlot *pAttr = pEle->xSlot;
364 5951 : pAttr->WriteSlotStubs( rShellName, rList, rOutStm );
365 : }
366 83 : }
367 :
368 190 : void SvMetaClass::WriteSfx( SvIdlDataBase & rBase, SvStream & rOutStm )
369 : {
370 190 : WriteStars( rOutStm );
371 : // define class
372 190 : rOutStm.WriteCharPtr( "#ifdef " ).WriteCharPtr( GetName().getString().getStr() ) << endl;
373 190 : rOutStm.WriteCharPtr( "#undef ShellClass" ) << endl;
374 190 : rOutStm.WriteCharPtr( "#undef " ).WriteCharPtr( GetName().getString().getStr() ) << endl;
375 190 : rOutStm.WriteCharPtr( "#define ShellClass " ).WriteCharPtr( GetName().getString().getStr() ) << endl;
376 :
377 : // no slotmaps get written for interfaces
378 190 : if( !IsShell() )
379 : {
380 107 : rOutStm.WriteCharPtr( "#endif" ) << endl << endl;
381 297 : return;
382 : }
383 : // write parameter array
384 83 : rOutStm.WriteCharPtr("static SfxFormalArgument a").WriteCharPtr(GetName().getString().getStr()).WriteCharPtr("Args_Impl[] =") << endl;
385 83 : rOutStm.WriteChar('{') << endl;
386 :
387 83 : std::vector<sal_uLong> aSuperList;
388 166 : SvMetaClassList classList;
389 166 : SvSlotElementList aSlotList;
390 83 : InsertSlots(aSlotList, aSuperList, classList, OString(), rBase);
391 6034 : for ( size_t i = 0, n = aSlotList.size(); i < n; ++i )
392 : {
393 5951 : SvSlotElement *pEle = aSlotList[ i ];
394 5951 : SvMetaSlot *pSlot = pEle->xSlot;
395 5951 : pSlot->SetListPos( i );
396 : }
397 :
398 83 : size_t nSlotCount = aSlotList.size();
399 :
400 : // write all attributes
401 83 : sal_uInt16 nArgCount = WriteSlotParamArray( rBase, aSlotList, rOutStm );
402 83 : if( nArgCount )
403 61 : Back2Delemitter( rOutStm );
404 : else
405 : {
406 : // at leaast one dummy
407 22 : WriteTab( rOutStm, 1 );
408 22 : rOutStm.WriteCharPtr("{ (const SfxType*) &aSfxVoidItem_Impl, 0, 0 }" ) << endl;
409 : }
410 83 : rOutStm << endl;
411 83 : rOutStm.WriteCharPtr( "};" ) << endl << endl;
412 :
413 166 : ByteStringList aStringList;
414 83 : WriteSlotStubs( GetName().getString(), aSlotList, aStringList, rOutStm );
415 721 : for ( size_t i = 0, n = aStringList.size(); i < n; ++i )
416 638 : delete aStringList[ i ];
417 83 : aStringList.clear();
418 :
419 83 : rOutStm << endl;
420 :
421 : // write slotmap
422 83 : rOutStm.WriteCharPtr("static SfxSlot a").WriteCharPtr(GetName().getString().getStr()).WriteCharPtr("Slots_Impl[] =") << endl;
423 83 : rOutStm.WriteChar( '{' ) << endl;
424 :
425 : // write all attributes
426 83 : WriteSlots( GetName().getString(), 0, aSlotList, rBase, rOutStm );
427 83 : if( nSlotCount )
428 76 : Back2Delemitter( rOutStm );
429 : else
430 : {
431 : // at least one dummy
432 7 : WriteTab( rOutStm, 1 );
433 7 : rOutStm.WriteCharPtr( "SFX_SLOT_ARG(" ).WriteCharPtr( GetName().getString().getStr() )
434 7 : .WriteCharPtr( ", 0, 0, " )
435 7 : .WriteCharPtr( "SFX_STUB_PTR_EXEC_NONE," )
436 7 : .WriteCharPtr( "SFX_STUB_PTR_STATE_NONE," )
437 7 : .WriteCharPtr( "SfxSlotMode::NONE, SfxVoidItem, 0, 0, \"\", SfxSlotMode::NONE )" ) << endl;
438 : }
439 83 : rOutStm << endl;
440 83 : rOutStm.WriteCharPtr( "};" ) << endl;
441 83 : rOutStm.WriteCharPtr( "#endif" ) << endl << endl;
442 :
443 6034 : for( size_t i = 0, n = aSlotList.size(); i < n; ++i )
444 : {
445 5951 : SvSlotElement* pEle = aSlotList[ i ];
446 5951 : SvMetaSlot* pAttr = pEle->xSlot;
447 5951 : pAttr->ResetSlotPointer();
448 : }
449 :
450 6034 : for( size_t i = 0, n = aSlotList.size(); i < n; ++i )
451 5951 : delete aSlotList[ i ];
452 166 : aSlotList.clear();
453 : }
454 :
455 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|