xref: /AOO41X/main/unodevtools/source/skeletonmaker/skeletoncommon.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir #include "osl/thread.hxx"
29*cdf0e10cSrcweir 
30*cdf0e10cSrcweir #include "codemaker/commonjava.hxx"
31*cdf0e10cSrcweir #include "codemaker/commoncpp.hxx"
32*cdf0e10cSrcweir #include "codemaker/generatedtypeset.hxx"
33*cdf0e10cSrcweir 
34*cdf0e10cSrcweir #include "skeletoncommon.hxx"
35*cdf0e10cSrcweir 
36*cdf0e10cSrcweir #include <iostream>
37*cdf0e10cSrcweir 
38*cdf0e10cSrcweir using namespace ::rtl;
39*cdf0e10cSrcweir using namespace ::codemaker::cpp;
40*cdf0e10cSrcweir 
41*cdf0e10cSrcweir namespace skeletonmaker {
42*cdf0e10cSrcweir 
43*cdf0e10cSrcweir void printLicenseHeader(std::ostream& o, rtl::OString const & filename)
44*cdf0e10cSrcweir {
45*cdf0e10cSrcweir     sal_Int32 index = -1;
46*cdf0e10cSrcweir #ifdef SAL_UNX
47*cdf0e10cSrcweir 	index = filename.lastIndexOf('/');
48*cdf0e10cSrcweir #else
49*cdf0e10cSrcweir 	index = filename.lastIndexOf('\\');
50*cdf0e10cSrcweir #endif
51*cdf0e10cSrcweir     OString shortfilename(filename);
52*cdf0e10cSrcweir     if ( index != -1 )
53*cdf0e10cSrcweir         shortfilename = filename.copy(index+1);
54*cdf0e10cSrcweir 
55*cdf0e10cSrcweir     o << "/*************************************************************************\n"
56*cdf0e10cSrcweir         " *\n"
57*cdf0e10cSrcweir         " * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n"
58*cdf0e10cSrcweir         " * \n"
59*cdf0e10cSrcweir         " * Copyright 2000, 2010 Oracle and/or its affiliates.\n"
60*cdf0e10cSrcweir         " *\n"
61*cdf0e10cSrcweir         " * OpenOffice.org - a multi-platform office productivity suite\n"
62*cdf0e10cSrcweir         " *\n"
63*cdf0e10cSrcweir         " * This file is part of OpenOffice.org.\n"
64*cdf0e10cSrcweir         " *\n"
65*cdf0e10cSrcweir         " * OpenOffice.org is free software: you can redistribute it and/or modify\n"
66*cdf0e10cSrcweir         " * it under the terms of the GNU Lesser General Public License version 3\n"
67*cdf0e10cSrcweir         " * only, as published by the Free Software Foundation.\n"
68*cdf0e10cSrcweir         " *\n"
69*cdf0e10cSrcweir         " * OpenOffice.org is distributed in the hope that it will be useful,\n"
70*cdf0e10cSrcweir         " * but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
71*cdf0e10cSrcweir         " * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
72*cdf0e10cSrcweir         " * GNU Lesser General Public License version 3 for more details\n"
73*cdf0e10cSrcweir         " * (a copy is included in the LICENSE file that accompanied this code).\n"
74*cdf0e10cSrcweir         " *\n"
75*cdf0e10cSrcweir         " * You should have received a copy of the GNU Lesser General Public License\n"
76*cdf0e10cSrcweir         " * version 3 along with OpenOffice.org.  If not, see\n"
77*cdf0e10cSrcweir         " * <http://www.openoffice.org/license.html>\n"
78*cdf0e10cSrcweir         " * for a copy of the LGPLv3 License.\n"
79*cdf0e10cSrcweir         " *\n"
80*cdf0e10cSrcweir         " ************************************************************************/\n\n";
81*cdf0e10cSrcweir }
82*cdf0e10cSrcweir 
83*cdf0e10cSrcweir bool getOutputStream(ProgramOptions const & options,
84*cdf0e10cSrcweir                      OString const & extension,
85*cdf0e10cSrcweir                      std::ostream** ppOutputStream,
86*cdf0e10cSrcweir                      OString & targetSourceFileName,
87*cdf0e10cSrcweir                      OString & tmpSourceFileName)
88*cdf0e10cSrcweir {
89*cdf0e10cSrcweir     bool bStandardout = false;
90*cdf0e10cSrcweir     if ( options.outputpath.equals("stdout") )
91*cdf0e10cSrcweir     {
92*cdf0e10cSrcweir         bStandardout = true;
93*cdf0e10cSrcweir         *ppOutputStream = &std::cout;
94*cdf0e10cSrcweir         return bStandardout;
95*cdf0e10cSrcweir     }
96*cdf0e10cSrcweir 
97*cdf0e10cSrcweir     targetSourceFileName = createFileNameFromType(
98*cdf0e10cSrcweir         options.outputpath, options.implname.replace('.','/'), extension);
99*cdf0e10cSrcweir 
100*cdf0e10cSrcweir     OString tmpDir = getTempDir(targetSourceFileName);
101*cdf0e10cSrcweir     FileStream file;
102*cdf0e10cSrcweir     file.createTempFile(tmpDir);
103*cdf0e10cSrcweir 
104*cdf0e10cSrcweir     if( !file.isValid() )
105*cdf0e10cSrcweir     {
106*cdf0e10cSrcweir         OString message("cannot open ");
107*cdf0e10cSrcweir         message += targetSourceFileName + " for writing";
108*cdf0e10cSrcweir         throw CannotDumpException(message);
109*cdf0e10cSrcweir     } else {
110*cdf0e10cSrcweir         tmpSourceFileName = file.getName();
111*cdf0e10cSrcweir     }
112*cdf0e10cSrcweir     file.close();
113*cdf0e10cSrcweir     *ppOutputStream = new std::ofstream(tmpSourceFileName.getStr(),
114*cdf0e10cSrcweir                                         std::ios_base::binary);
115*cdf0e10cSrcweir 
116*cdf0e10cSrcweir     return bStandardout;
117*cdf0e10cSrcweir }
118*cdf0e10cSrcweir 
119*cdf0e10cSrcweir codemaker::UnoType::Sort decomposeResolveAndCheck(
120*cdf0e10cSrcweir     TypeManager const & manager, OString const & type,
121*cdf0e10cSrcweir     bool resolveTypedefs, bool allowVoid, bool allowExtraEntities,
122*cdf0e10cSrcweir     RTTypeClass * typeClass, OString * name, sal_Int32 * rank,
123*cdf0e10cSrcweir     std::vector< OString > * arguments)
124*cdf0e10cSrcweir {
125*cdf0e10cSrcweir     codemaker::UnoType::Sort sort = codemaker::decomposeAndResolve(
126*cdf0e10cSrcweir         manager, type, resolveTypedefs, allowVoid, allowExtraEntities,
127*cdf0e10cSrcweir         typeClass, name, rank, arguments);
128*cdf0e10cSrcweir     for ( std::vector< OString >::iterator i(arguments->begin());
129*cdf0e10cSrcweir           i != arguments->end(); ++i )
130*cdf0e10cSrcweir     {
131*cdf0e10cSrcweir         RTTypeClass typeClass2;
132*cdf0e10cSrcweir         OString name2;
133*cdf0e10cSrcweir         sal_Int32 rank2;
134*cdf0e10cSrcweir         std::vector< OString > arguments2;
135*cdf0e10cSrcweir         decomposeResolveAndCheck(
136*cdf0e10cSrcweir             manager, *i, true, false, false, &typeClass2, &name2, &rank2,
137*cdf0e10cSrcweir             &arguments2);
138*cdf0e10cSrcweir     }
139*cdf0e10cSrcweir     return sort;
140*cdf0e10cSrcweir }
141*cdf0e10cSrcweir 
142*cdf0e10cSrcweir bool containsAttribute(AttributeInfo& attributes, OString const & attrname)
143*cdf0e10cSrcweir {
144*cdf0e10cSrcweir     for ( AttributeInfo::const_iterator i(attributes.begin());
145*cdf0e10cSrcweir           i != attributes.end(); ++i ) {
146*cdf0e10cSrcweir         if ( (*i).first == attrname ) {
147*cdf0e10cSrcweir             return true;
148*cdf0e10cSrcweir         }
149*cdf0e10cSrcweir     }
150*cdf0e10cSrcweir     return false;
151*cdf0e10cSrcweir }
152*cdf0e10cSrcweir 
153*cdf0e10cSrcweir // collect attributes including inherited attributes
154*cdf0e10cSrcweir void checkAttributes(TypeManager const & manager,
155*cdf0e10cSrcweir                      const typereg::Reader& reader,
156*cdf0e10cSrcweir                      AttributeInfo& attributes,
157*cdf0e10cSrcweir                      std::hash_set< OString, OStringHash >& propinterfaces)
158*cdf0e10cSrcweir {
159*cdf0e10cSrcweir     OString typeName = codemaker::convertString(reader.getTypeName());
160*cdf0e10cSrcweir     if ( typeName.equals("com/sun/star/beans/XPropertySet") ||
161*cdf0e10cSrcweir          typeName.equals("com/sun/star/beans/XFastPropertySet") ||
162*cdf0e10cSrcweir //        typeName.equals("com/sun/star/beans/XMultiPropertySet") ||
163*cdf0e10cSrcweir          typeName.equals("com/sun/star/beans/XPropertyAccess") )
164*cdf0e10cSrcweir     {
165*cdf0e10cSrcweir         propinterfaces.insert(typeName);
166*cdf0e10cSrcweir     }
167*cdf0e10cSrcweir 
168*cdf0e10cSrcweir     for ( sal_uInt16 i = 0; i < reader.getSuperTypeCount(); ++i ) {
169*cdf0e10cSrcweir         typereg::Reader supertype(manager.getTypeReader(
170*cdf0e10cSrcweir                                   codemaker::convertString(
171*cdf0e10cSrcweir                                       reader.getSuperTypeName(i))));
172*cdf0e10cSrcweir         if ( !supertype.isValid() ) {
173*cdf0e10cSrcweir             throw CannotDumpException(
174*cdf0e10cSrcweir                 "Bad type library entity "
175*cdf0e10cSrcweir                 + codemaker::convertString(reader.getSuperTypeName(i)));
176*cdf0e10cSrcweir         }
177*cdf0e10cSrcweir         checkAttributes(manager, supertype, attributes, propinterfaces);
178*cdf0e10cSrcweir     }
179*cdf0e10cSrcweir 
180*cdf0e10cSrcweir     for ( sal_uInt16 i = 0; i < reader.getFieldCount(); ++i ) {
181*cdf0e10cSrcweir         OString fieldName(
182*cdf0e10cSrcweir             codemaker::convertString(reader.getFieldName(i)).
183*cdf0e10cSrcweir             replace('/', '.'));
184*cdf0e10cSrcweir 
185*cdf0e10cSrcweir         if ( !containsAttribute(attributes, fieldName) ) {
186*cdf0e10cSrcweir             OString fieldType(
187*cdf0e10cSrcweir                 codemaker::convertString(reader.getFieldTypeName(i)).
188*cdf0e10cSrcweir                 replace('/', '.'));
189*cdf0e10cSrcweir             attributes.push_back(AttributeInfo::value_type(
190*cdf0e10cSrcweir                                      fieldName, std::pair<OString, sal_Int16>(
191*cdf0e10cSrcweir                                          fieldType, reader.getFieldFlags(i))));
192*cdf0e10cSrcweir         }
193*cdf0e10cSrcweir     }
194*cdf0e10cSrcweir }
195*cdf0e10cSrcweir 
196*cdf0e10cSrcweir void checkType(TypeManager const & manager,
197*cdf0e10cSrcweir                OString const & type,
198*cdf0e10cSrcweir                std::hash_set< OString, OStringHash >& interfaceTypes,
199*cdf0e10cSrcweir                std::hash_set< OString, OStringHash >& serviceTypes,
200*cdf0e10cSrcweir                AttributeInfo& properties)
201*cdf0e10cSrcweir {
202*cdf0e10cSrcweir 
203*cdf0e10cSrcweir     OString binType(type.replace('.', '/'));
204*cdf0e10cSrcweir     typereg::Reader reader(manager.getTypeReader(binType));
205*cdf0e10cSrcweir     if ( !reader.isValid() ) {
206*cdf0e10cSrcweir         throw CannotDumpException("Bad type library entity " + binType);
207*cdf0e10cSrcweir     }
208*cdf0e10cSrcweir 
209*cdf0e10cSrcweir     switch ( reader.getTypeClass() )
210*cdf0e10cSrcweir     {
211*cdf0e10cSrcweir     case RT_TYPE_INTERFACE:
212*cdf0e10cSrcweir     {
213*cdf0e10cSrcweir         // com/sun/star/lang/XComponent should be also not in the list
214*cdf0e10cSrcweir         // but it will be used for checking the impl helper and will be
215*cdf0e10cSrcweir         // removed later if necessary.
216*cdf0e10cSrcweir         if ( binType.equals("com/sun/star/lang/XTypeProvider") ||
217*cdf0e10cSrcweir              binType.equals("com/sun/star/uno/XWeak") )
218*cdf0e10cSrcweir             return;
219*cdf0e10cSrcweir         if (interfaceTypes.find(type) == interfaceTypes.end()) {
220*cdf0e10cSrcweir             interfaceTypes.insert(type);
221*cdf0e10cSrcweir         }
222*cdf0e10cSrcweir     }
223*cdf0e10cSrcweir         break;
224*cdf0e10cSrcweir     case RT_TYPE_SERVICE:
225*cdf0e10cSrcweir         if ( serviceTypes.find(binType) == serviceTypes.end() ) {
226*cdf0e10cSrcweir             serviceTypes.insert(binType);
227*cdf0e10cSrcweir 
228*cdf0e10cSrcweir             if ( reader.getSuperTypeCount() > 0 ) {
229*cdf0e10cSrcweir                 OString supername(codemaker::convertString(
230*cdf0e10cSrcweir                     reader.getSuperTypeName(0).replace('/', '.')));
231*cdf0e10cSrcweir 				if ( interfaceTypes.find(supername) == interfaceTypes.end() ) {
232*cdf0e10cSrcweir                     interfaceTypes.insert(supername);
233*cdf0e10cSrcweir 
234*cdf0e10cSrcweir 					typereg::Reader supertype(manager.getTypeReader(
235*cdf0e10cSrcweir                                   codemaker::convertString(
236*cdf0e10cSrcweir                                       reader.getSuperTypeName(0))));
237*cdf0e10cSrcweir 					if ( !supertype.isValid() ) {
238*cdf0e10cSrcweir 						throw CannotDumpException(
239*cdf0e10cSrcweir 							"Bad type library entity "
240*cdf0e10cSrcweir 							+ codemaker::convertString(reader.getSuperTypeName(0)));
241*cdf0e10cSrcweir 					}
242*cdf0e10cSrcweir 				}
243*cdf0e10cSrcweir 
244*cdf0e10cSrcweir                 // check if constructors are specified, if yes automatically
245*cdf0e10cSrcweir                 // support of XInitialization. We will take care of the default
246*cdf0e10cSrcweir                 // constructor because in this case XInitialization is not called.
247*cdf0e10cSrcweir                 if ( reader.getMethodCount() > 1 ||
248*cdf0e10cSrcweir                      ( reader.getMethodCount() == 1 &&
249*cdf0e10cSrcweir                        reader.getMethodName(0).getLength() > 0 ) )
250*cdf0e10cSrcweir                 {
251*cdf0e10cSrcweir                     OString s("com.sun.star.lang.XInitialization");
252*cdf0e10cSrcweir                     if ( interfaceTypes.find(s) == interfaceTypes.end() )
253*cdf0e10cSrcweir                         interfaceTypes.insert(s);
254*cdf0e10cSrcweir                 }
255*cdf0e10cSrcweir             } else {
256*cdf0e10cSrcweir                 for ( sal_uInt16 i = 0; i < reader.getReferenceCount(); ++i ) {
257*cdf0e10cSrcweir                     OString referenceType(
258*cdf0e10cSrcweir                         codemaker::convertString(
259*cdf0e10cSrcweir                             reader.getReferenceTypeName(i)).replace('/', '.'));
260*cdf0e10cSrcweir 
261*cdf0e10cSrcweir                     if ( reader.getReferenceSort(i) == RT_REF_SUPPORTS ) {
262*cdf0e10cSrcweir                         checkType(manager, referenceType, interfaceTypes,
263*cdf0e10cSrcweir                                   serviceTypes, properties);
264*cdf0e10cSrcweir                     } else if ( reader.getReferenceSort(i) == RT_REF_EXPORTS ) {
265*cdf0e10cSrcweir                         checkType(manager, referenceType, interfaceTypes,
266*cdf0e10cSrcweir                                   serviceTypes, properties);
267*cdf0e10cSrcweir                     }
268*cdf0e10cSrcweir                 }
269*cdf0e10cSrcweir 
270*cdf0e10cSrcweir                 for ( sal_uInt16 i = 0; i < reader.getFieldCount(); ++i ) {
271*cdf0e10cSrcweir                     OString fieldName(
272*cdf0e10cSrcweir                         codemaker::convertString(reader.getFieldName(i)).
273*cdf0e10cSrcweir                         replace('/', '.'));
274*cdf0e10cSrcweir                     OString fieldType(
275*cdf0e10cSrcweir                         codemaker::convertString(reader.getFieldTypeName(i)).
276*cdf0e10cSrcweir                         replace('/', '.'));
277*cdf0e10cSrcweir 
278*cdf0e10cSrcweir                     properties.push_back(AttributeInfo::value_type(
279*cdf0e10cSrcweir                         fieldName, std::pair<OString, sal_Int16>(
280*cdf0e10cSrcweir                             fieldType, reader.getFieldFlags(i))));
281*cdf0e10cSrcweir                 }
282*cdf0e10cSrcweir             }
283*cdf0e10cSrcweir         }
284*cdf0e10cSrcweir         break;
285*cdf0e10cSrcweir     default:
286*cdf0e10cSrcweir         OSL_ASSERT(false);
287*cdf0e10cSrcweir         break;
288*cdf0e10cSrcweir     }
289*cdf0e10cSrcweir }
290*cdf0e10cSrcweir 
291*cdf0e10cSrcweir void checkDefaultInterfaces(
292*cdf0e10cSrcweir          std::hash_set< OString, OStringHash >& interfaces,
293*cdf0e10cSrcweir          const std::hash_set< OString, OStringHash >& services,
294*cdf0e10cSrcweir        const OString & propertyhelper)
295*cdf0e10cSrcweir {
296*cdf0e10cSrcweir     if ( services.empty() ) {
297*cdf0e10cSrcweir         if (interfaces.find("com.sun.star.lang.XServiceInfo") != interfaces.end())
298*cdf0e10cSrcweir             interfaces.erase("com.sun.star.lang.XServiceInfo");
299*cdf0e10cSrcweir     } else {
300*cdf0e10cSrcweir         if (interfaces.find("com.sun.star.lang.XServiceInfo") == interfaces.end())
301*cdf0e10cSrcweir             interfaces.insert("com.sun.star.lang.XServiceInfo");
302*cdf0e10cSrcweir     }
303*cdf0e10cSrcweir 
304*cdf0e10cSrcweir     if ( propertyhelper.equals("_") ) {
305*cdf0e10cSrcweir         if (interfaces.find("com.sun.star.beans.XPropertySet")
306*cdf0e10cSrcweir             != interfaces.end())
307*cdf0e10cSrcweir             interfaces.erase("com.sun.star.beans.XPropertySet");
308*cdf0e10cSrcweir         if (interfaces.find("com.sun.star.beans.XFastPropertySet")
309*cdf0e10cSrcweir             != interfaces.end())
310*cdf0e10cSrcweir             interfaces.erase("com.sun.star.beans.XFastPropertySet");
311*cdf0e10cSrcweir         if (interfaces.find("com.sun.star.beans.XPropertyAccess")
312*cdf0e10cSrcweir             != interfaces.end())
313*cdf0e10cSrcweir             interfaces.erase("com.sun.star.beans.XPropertyAccess");
314*cdf0e10cSrcweir     }
315*cdf0e10cSrcweir }
316*cdf0e10cSrcweir 
317*cdf0e10cSrcweir bool checkServiceProperties(TypeManager const & manager,
318*cdf0e10cSrcweir                             const typereg::Reader & reader)
319*cdf0e10cSrcweir {
320*cdf0e10cSrcweir     if ( reader.getFieldCount() > 0 )
321*cdf0e10cSrcweir         return true;
322*cdf0e10cSrcweir 
323*cdf0e10cSrcweir     if ( reader.getReferenceCount() > 0 ) {
324*cdf0e10cSrcweir         for ( sal_uInt16 i = 0; i < reader.getReferenceCount(); ++i ) {
325*cdf0e10cSrcweir             if ( reader.getReferenceSort(i) == RT_REF_EXPORTS ) {
326*cdf0e10cSrcweir                 typereg::Reader refreader(
327*cdf0e10cSrcweir                     manager.getTypeReader(
328*cdf0e10cSrcweir                         codemaker::convertString(reader.getReferenceTypeName(i))));
329*cdf0e10cSrcweir 
330*cdf0e10cSrcweir                 if ( checkServiceProperties(manager, refreader) )
331*cdf0e10cSrcweir                     return true;
332*cdf0e10cSrcweir             }
333*cdf0e10cSrcweir         }
334*cdf0e10cSrcweir     }
335*cdf0e10cSrcweir     return false;
336*cdf0e10cSrcweir }
337*cdf0e10cSrcweir 
338*cdf0e10cSrcweir 
339*cdf0e10cSrcweir OString checkPropertyHelper(
340*cdf0e10cSrcweir     ProgramOptions const & options,
341*cdf0e10cSrcweir     TypeManager const & manager,
342*cdf0e10cSrcweir     const std::hash_set< OString, OStringHash >& services,
343*cdf0e10cSrcweir     const std::hash_set< OString, OStringHash >& interfaces,
344*cdf0e10cSrcweir     AttributeInfo& attributes,
345*cdf0e10cSrcweir     std::hash_set< OString, OStringHash >& propinterfaces)
346*cdf0e10cSrcweir {
347*cdf0e10cSrcweir     std::hash_set< OString, OStringHash >::const_iterator iter;
348*cdf0e10cSrcweir     std::hash_set< OString, OStringHash >::const_iterator end;
349*cdf0e10cSrcweir 
350*cdf0e10cSrcweir     if ( !services.empty() ) {
351*cdf0e10cSrcweir         iter = services.begin();
352*cdf0e10cSrcweir         end = services.end();
353*cdf0e10cSrcweir     } else {
354*cdf0e10cSrcweir         iter = interfaces.begin();
355*cdf0e10cSrcweir         end = interfaces.end();
356*cdf0e10cSrcweir     }
357*cdf0e10cSrcweir 
358*cdf0e10cSrcweir     bool oldStyleWithProperties = false;
359*cdf0e10cSrcweir     while ( iter != end ) {
360*cdf0e10cSrcweir         typereg::Reader reader(manager.getTypeReader((*iter).replace('.', '/')));
361*cdf0e10cSrcweir 
362*cdf0e10cSrcweir         if ( !services.empty() ) {
363*cdf0e10cSrcweir             if ( options.supportpropertysetmixin && reader.getSuperTypeCount() > 0 )
364*cdf0e10cSrcweir             {
365*cdf0e10cSrcweir                 typereg::Reader supertype(
366*cdf0e10cSrcweir                     manager.getTypeReader(
367*cdf0e10cSrcweir                         codemaker::convertString(
368*cdf0e10cSrcweir                             reader.getSuperTypeName(0))));
369*cdf0e10cSrcweir                 if ( !supertype.isValid() ) {
370*cdf0e10cSrcweir                     throw CannotDumpException(
371*cdf0e10cSrcweir                         "Bad type library entity "
372*cdf0e10cSrcweir                         + codemaker::convertString(
373*cdf0e10cSrcweir                             reader.getSuperTypeName(0)));
374*cdf0e10cSrcweir                 }
375*cdf0e10cSrcweir 
376*cdf0e10cSrcweir                 checkAttributes(manager, supertype, attributes, propinterfaces);
377*cdf0e10cSrcweir 
378*cdf0e10cSrcweir                 if ( !(attributes.empty() || propinterfaces.empty()) ) {
379*cdf0e10cSrcweir                     return OUStringToOString(
380*cdf0e10cSrcweir                         supertype.getTypeName().replace('/', '.'),
381*cdf0e10cSrcweir                         osl_getThreadTextEncoding());
382*cdf0e10cSrcweir                 }
383*cdf0e10cSrcweir             } else {
384*cdf0e10cSrcweir                 oldStyleWithProperties = checkServiceProperties(manager, reader);
385*cdf0e10cSrcweir             }
386*cdf0e10cSrcweir         } else {
387*cdf0e10cSrcweir             checkAttributes(manager, reader, attributes, propinterfaces);
388*cdf0e10cSrcweir             if ( !(attributes.empty() || propinterfaces.empty()) ) {
389*cdf0e10cSrcweir                 return OUStringToOString(
390*cdf0e10cSrcweir                     reader.getTypeName().replace('/', '.'),
391*cdf0e10cSrcweir                     osl_getThreadTextEncoding());
392*cdf0e10cSrcweir             }
393*cdf0e10cSrcweir         }
394*cdf0e10cSrcweir         iter++;
395*cdf0e10cSrcweir     }
396*cdf0e10cSrcweir 
397*cdf0e10cSrcweir     return (oldStyleWithProperties ? "_" : "");
398*cdf0e10cSrcweir }
399*cdf0e10cSrcweir 
400*cdf0e10cSrcweir bool checkXComponentSupport(TypeManager const & manager,
401*cdf0e10cSrcweir                             typereg::Reader const & reader)
402*cdf0e10cSrcweir {
403*cdf0e10cSrcweir     static OUString s(RTL_CONSTASCII_USTRINGPARAM(
404*cdf0e10cSrcweir                                "com/sun/star/lang/XComponent"));
405*cdf0e10cSrcweir     if ( reader.getTypeName().equals(s) )
406*cdf0e10cSrcweir         return true;
407*cdf0e10cSrcweir 
408*cdf0e10cSrcweir     for ( sal_uInt16 i = 0; i < reader.getSuperTypeCount(); ++i ) {
409*cdf0e10cSrcweir         typereg::Reader super(
410*cdf0e10cSrcweir             manager.getTypeReader(
411*cdf0e10cSrcweir                 codemaker::convertString(
412*cdf0e10cSrcweir                     reader.getSuperTypeName(i))));
413*cdf0e10cSrcweir         if ( !super.isValid() ) {
414*cdf0e10cSrcweir             throw CannotDumpException(
415*cdf0e10cSrcweir                 "Bad type library entity "
416*cdf0e10cSrcweir                 + codemaker::convertString(
417*cdf0e10cSrcweir                     reader.getSuperTypeName(i)));
418*cdf0e10cSrcweir         }
419*cdf0e10cSrcweir         if ( checkXComponentSupport(manager, super) )
420*cdf0e10cSrcweir             return true;
421*cdf0e10cSrcweir     }
422*cdf0e10cSrcweir 
423*cdf0e10cSrcweir     return false;
424*cdf0e10cSrcweir }
425*cdf0e10cSrcweir 
426*cdf0e10cSrcweir 
427*cdf0e10cSrcweir // if XComponent is directly specified, return true and remove it from the
428*cdf0e10cSrcweir // supported interfaces list
429*cdf0e10cSrcweir bool checkXComponentSupport(TypeManager const & manager,
430*cdf0e10cSrcweir          std::hash_set< OString, OStringHash >& interfaces)
431*cdf0e10cSrcweir {
432*cdf0e10cSrcweir     if ( interfaces.empty() )
433*cdf0e10cSrcweir         return false;
434*cdf0e10cSrcweir 
435*cdf0e10cSrcweir     std::hash_set< OString, OStringHash >::const_iterator iter =
436*cdf0e10cSrcweir         interfaces.begin();
437*cdf0e10cSrcweir     while ( iter != interfaces.end() ) {
438*cdf0e10cSrcweir         if ( (*iter).equals("com.sun.star.lang.XComponent") ) {
439*cdf0e10cSrcweir             interfaces.erase("com.sun.star.lang.XComponent");
440*cdf0e10cSrcweir             return true;
441*cdf0e10cSrcweir         }
442*cdf0e10cSrcweir         typereg::Reader reader(manager.getTypeReader((*iter).replace('.', '/')));
443*cdf0e10cSrcweir         if ( checkXComponentSupport(manager, reader) )
444*cdf0e10cSrcweir             return true;
445*cdf0e10cSrcweir         iter++;
446*cdf0e10cSrcweir     }
447*cdf0e10cSrcweir 
448*cdf0e10cSrcweir     return false;
449*cdf0e10cSrcweir }
450*cdf0e10cSrcweir 
451*cdf0e10cSrcweir sal_uInt16 checkAdditionalPropertyFlags(typereg::Reader const & reader,
452*cdf0e10cSrcweir                                         sal_uInt16 field, sal_uInt16 method)
453*cdf0e10cSrcweir {
454*cdf0e10cSrcweir     sal_uInt16 flags = 0;
455*cdf0e10cSrcweir     bool getterSupportsUnknown = false;
456*cdf0e10cSrcweir 
457*cdf0e10cSrcweir     OUString su(RTL_CONSTASCII_USTRINGPARAM(
458*cdf0e10cSrcweir                    "com/sun/star/beans/UnknownPropertyException"));
459*cdf0e10cSrcweir     if ( method < reader.getMethodCount()
460*cdf0e10cSrcweir          && reader.getMethodFlags(method) == RT_MODE_ATTRIBUTE_GET
461*cdf0e10cSrcweir          && reader.getMethodName(method) == reader.getFieldName(field) )
462*cdf0e10cSrcweir     {
463*cdf0e10cSrcweir         if ( reader.getMethodExceptionCount(method) > 0 ) {
464*cdf0e10cSrcweir             for ( sal_uInt16 i = 0; i < reader.getMethodExceptionCount(method);
465*cdf0e10cSrcweir                   ++i )
466*cdf0e10cSrcweir             {
467*cdf0e10cSrcweir                 if (su.equals(reader.getMethodExceptionTypeName(method, i)))
468*cdf0e10cSrcweir                     getterSupportsUnknown = true;
469*cdf0e10cSrcweir             }
470*cdf0e10cSrcweir         }
471*cdf0e10cSrcweir         method++;
472*cdf0e10cSrcweir     }
473*cdf0e10cSrcweir     if ( method < reader.getMethodCount()
474*cdf0e10cSrcweir          && reader.getMethodFlags(method) == RT_MODE_ATTRIBUTE_SET
475*cdf0e10cSrcweir          && reader.getMethodName(method) == reader.getFieldName(field) )
476*cdf0e10cSrcweir     {
477*cdf0e10cSrcweir         if ( reader.getMethodExceptionCount(method) > 0 ) {
478*cdf0e10cSrcweir             OUString s(RTL_CONSTASCII_USTRINGPARAM(
479*cdf0e10cSrcweir                            "com/sun/star/beans/PropertyVetoException"));
480*cdf0e10cSrcweir             for ( sal_uInt16 i = 0; i < reader.getMethodExceptionCount(method);
481*cdf0e10cSrcweir                   ++i )
482*cdf0e10cSrcweir             {
483*cdf0e10cSrcweir                 if ( s.equals(reader.getMethodExceptionTypeName(method, i)) )
484*cdf0e10cSrcweir                     flags |= RT_ACCESS_CONSTRAINED;
485*cdf0e10cSrcweir                 if ( getterSupportsUnknown &&
486*cdf0e10cSrcweir                      su.equals(reader.getMethodExceptionTypeName(method, i)) )
487*cdf0e10cSrcweir                     flags |= RT_ACCESS_OPTIONAL;
488*cdf0e10cSrcweir             }
489*cdf0e10cSrcweir         }
490*cdf0e10cSrcweir     }
491*cdf0e10cSrcweir     return flags;
492*cdf0e10cSrcweir }
493*cdf0e10cSrcweir 
494*cdf0e10cSrcweir // This function checks if the specified types for paramters and return
495*cdf0e10cSrcweir // types are allowed add-in types, for more info see the com.sun.star.sheet.AddIn
496*cdf0e10cSrcweir // service description
497*cdf0e10cSrcweir bool checkAddinType(TypeManager const & manager,
498*cdf0e10cSrcweir                     OString const & type, bool & bLastAny,
499*cdf0e10cSrcweir                     bool & bHasXPropertySet, bool bIsReturn)
500*cdf0e10cSrcweir {
501*cdf0e10cSrcweir     RTTypeClass typeClass;
502*cdf0e10cSrcweir     OString name;
503*cdf0e10cSrcweir     sal_Int32 rank;
504*cdf0e10cSrcweir     std::vector< OString > arguments;
505*cdf0e10cSrcweir     codemaker::UnoType::Sort sort = codemaker::decomposeAndResolve(
506*cdf0e10cSrcweir         manager, type, true, true, true, &typeClass, &name, &rank, &arguments);
507*cdf0e10cSrcweir 
508*cdf0e10cSrcweir     if ( sort == codemaker::UnoType::SORT_LONG ||
509*cdf0e10cSrcweir          sort == codemaker::UnoType::SORT_DOUBLE ||
510*cdf0e10cSrcweir          sort == codemaker::UnoType::SORT_STRING )
511*cdf0e10cSrcweir     {
512*cdf0e10cSrcweir         if ( rank == 0 || rank ==2 )
513*cdf0e10cSrcweir             return true;
514*cdf0e10cSrcweir     }
515*cdf0e10cSrcweir     if ( sort == codemaker::UnoType::SORT_ANY )
516*cdf0e10cSrcweir     {
517*cdf0e10cSrcweir         if ( rank <= 2 ) {
518*cdf0e10cSrcweir             if ( rank ==1 ) {
519*cdf0e10cSrcweir                 if ( bIsReturn )
520*cdf0e10cSrcweir                     return false;
521*cdf0e10cSrcweir                 bLastAny = true;
522*cdf0e10cSrcweir             }
523*cdf0e10cSrcweir 
524*cdf0e10cSrcweir             return true;
525*cdf0e10cSrcweir         }
526*cdf0e10cSrcweir     }
527*cdf0e10cSrcweir     if ( sort == codemaker::UnoType::SORT_COMPLEX &&
528*cdf0e10cSrcweir          typeClass == RT_TYPE_INTERFACE )
529*cdf0e10cSrcweir     {
530*cdf0e10cSrcweir         if ( bIsReturn && type.equals("com/sun/star/sheet/XVolatileResult") )
531*cdf0e10cSrcweir             return true;
532*cdf0e10cSrcweir         if ( !bIsReturn && type.equals("com/sun/star/table/XCellRange") )
533*cdf0e10cSrcweir             return true;
534*cdf0e10cSrcweir         if ( !bIsReturn && type.equals("com/sun/star/beans/XPropertySet") )
535*cdf0e10cSrcweir         {
536*cdf0e10cSrcweir             if ( bHasXPropertySet ) {
537*cdf0e10cSrcweir                 return false;
538*cdf0e10cSrcweir             } else {
539*cdf0e10cSrcweir                 bHasXPropertySet = true;
540*cdf0e10cSrcweir                 return true;
541*cdf0e10cSrcweir             }
542*cdf0e10cSrcweir         }
543*cdf0e10cSrcweir     }
544*cdf0e10cSrcweir     return false;
545*cdf0e10cSrcweir }
546*cdf0e10cSrcweir 
547*cdf0e10cSrcweir void checkAddInTypes(TypeManager const & manager,
548*cdf0e10cSrcweir                      typereg::Reader const & reader)
549*cdf0e10cSrcweir {
550*cdf0e10cSrcweir     OString sType(codemaker::convertString(reader.getTypeName()).replace('/', '.'));
551*cdf0e10cSrcweir     bool bLastAny = false;
552*cdf0e10cSrcweir     bool bHasXPropertySet = false;
553*cdf0e10cSrcweir     for ( sal_uInt16 m = 0; m < reader.getMethodCount(); ++m ) {
554*cdf0e10cSrcweir         OString sMethod(codemaker::convertString(reader.getMethodName(m)));
555*cdf0e10cSrcweir 
556*cdf0e10cSrcweir         OString sReturnType(codemaker::convertString(
557*cdf0e10cSrcweir                                 reader.getMethodReturnTypeName(m)));
558*cdf0e10cSrcweir         if ( !checkAddinType(
559*cdf0e10cSrcweir                  manager, sReturnType, bLastAny, bHasXPropertySet, true) )
560*cdf0e10cSrcweir         {
561*cdf0e10cSrcweir             OStringBuffer msg("the return type of the calc add-in function '");
562*cdf0e10cSrcweir             msg.append(sType);
563*cdf0e10cSrcweir             msg.append(":");
564*cdf0e10cSrcweir             msg.append(sMethod);
565*cdf0e10cSrcweir             msg.append("' is invalid. Please check your IDL defintion.");
566*cdf0e10cSrcweir             throw CannotDumpException(msg.makeStringAndClear());
567*cdf0e10cSrcweir         }
568*cdf0e10cSrcweir 
569*cdf0e10cSrcweir         bHasXPropertySet = false;
570*cdf0e10cSrcweir         for ( sal_uInt16 p = 0; p < reader.getMethodParameterCount(m); ++p ) {
571*cdf0e10cSrcweir             bLastAny = false;
572*cdf0e10cSrcweir             OString sParamType(codemaker::convertString(
573*cdf0e10cSrcweir                                    reader.getMethodParameterTypeName(m, p)));
574*cdf0e10cSrcweir             if ( !checkAddinType(manager, sParamType,
575*cdf0e10cSrcweir                                 bLastAny, bHasXPropertySet, false) ||
576*cdf0e10cSrcweir                  bLastAny )
577*cdf0e10cSrcweir             {
578*cdf0e10cSrcweir                 OStringBuffer msg("the type of the ");
579*cdf0e10cSrcweir                 msg.append((sal_Int32)p+1);
580*cdf0e10cSrcweir                 msg.append(". parameter of the calc add-in function '");
581*cdf0e10cSrcweir                 msg.append(sType);
582*cdf0e10cSrcweir                 msg.append(":");
583*cdf0e10cSrcweir                 msg.append(sMethod);
584*cdf0e10cSrcweir                 msg.append("' is invalid.");
585*cdf0e10cSrcweir                 if ( bLastAny )
586*cdf0e10cSrcweir                     msg.append(" The type 'sequence<any>' is allowed as last "
587*cdf0e10cSrcweir                                "parameter only.");
588*cdf0e10cSrcweir                 if ( bHasXPropertySet )
589*cdf0e10cSrcweir                     msg.append(" The type 'XPropertySet' is allowed only once.");
590*cdf0e10cSrcweir 
591*cdf0e10cSrcweir                 msg.append(" Please check your IDL definition.");
592*cdf0e10cSrcweir                 throw CannotDumpException(msg.makeStringAndClear());
593*cdf0e10cSrcweir             }
594*cdf0e10cSrcweir         }
595*cdf0e10cSrcweir     }
596*cdf0e10cSrcweir }
597*cdf0e10cSrcweir 
598*cdf0e10cSrcweir void generateFunctionParamterMap(std::ostream& o,
599*cdf0e10cSrcweir                                  ProgramOptions const & options,
600*cdf0e10cSrcweir                                  TypeManager const & manager,
601*cdf0e10cSrcweir                                  typereg::Reader const & reader,
602*cdf0e10cSrcweir                                  ::codemaker::GeneratedTypeSet & generated,
603*cdf0e10cSrcweir                                  bool bFirst)
604*cdf0e10cSrcweir {
605*cdf0e10cSrcweir     OString sType(codemaker::convertString(reader.getTypeName()));
606*cdf0e10cSrcweir     if ( sType.equals("com/sun/star/uno/XInterface") ||
607*cdf0e10cSrcweir          sType.equals("com/sun/star/lang/XLocalizable") ||
608*cdf0e10cSrcweir          sType.equals("com/sun/star/lang/XServiceInfo") ||
609*cdf0e10cSrcweir          // the next three checks becomes obsolete when configuration is used
610*cdf0e10cSrcweir          sType.equals("com/sun/star/sheet/XAddIn") ||
611*cdf0e10cSrcweir          sType.equals("com/sun/star/sheet/XCompatibilityNames") ||
612*cdf0e10cSrcweir          sType.equals("com/sun/star/lang/XServiceName") )
613*cdf0e10cSrcweir     {
614*cdf0e10cSrcweir         return;
615*cdf0e10cSrcweir     }
616*cdf0e10cSrcweir 
617*cdf0e10cSrcweir     // check if the specified add-in functions supports valid types
618*cdf0e10cSrcweir     checkAddInTypes(manager, reader);
619*cdf0e10cSrcweir 
620*cdf0e10cSrcweir     for ( sal_uInt16 i = 0; i < reader.getSuperTypeCount(); ++i ) {
621*cdf0e10cSrcweir         typereg::Reader super(
622*cdf0e10cSrcweir             manager.getTypeReader(
623*cdf0e10cSrcweir                 codemaker::convertString(
624*cdf0e10cSrcweir                     reader.getSuperTypeName(i))));
625*cdf0e10cSrcweir         if ( !super.isValid() ) {
626*cdf0e10cSrcweir             throw CannotDumpException(
627*cdf0e10cSrcweir                 "Bad type library entity "
628*cdf0e10cSrcweir                 + codemaker::convertString(
629*cdf0e10cSrcweir                     reader.getSuperTypeName(i)));
630*cdf0e10cSrcweir         }
631*cdf0e10cSrcweir         generateFunctionParamterMap(o, options, manager, super, generated, bFirst);
632*cdf0e10cSrcweir     }
633*cdf0e10cSrcweir 
634*cdf0e10cSrcweir     OString type(codemaker::convertString(reader.getTypeName()));
635*cdf0e10cSrcweir     if ( generated.contains(type) )
636*cdf0e10cSrcweir         return;
637*cdf0e10cSrcweir     else
638*cdf0e10cSrcweir         generated.add(type);
639*cdf0e10cSrcweir 
640*cdf0e10cSrcweir     for ( sal_uInt16 m = 0; m < reader.getMethodCount(); ++m ) {
641*cdf0e10cSrcweir         OString sMethod(codemaker::convertString(reader.getMethodName(m)));
642*cdf0e10cSrcweir 
643*cdf0e10cSrcweir         if ( bFirst ) {
644*cdf0e10cSrcweir             if (options.language == 2) {
645*cdf0e10cSrcweir                 o << "        ParamMap fpm;\n";
646*cdf0e10cSrcweir             }
647*cdf0e10cSrcweir             else {
648*cdf0e10cSrcweir                 if ( options.java5 )
649*cdf0e10cSrcweir                     o << "        java.util.Hashtable< Integer, String > fpm = "
650*cdf0e10cSrcweir                         "new java.util.Hashtable< Integer, String >();\n";
651*cdf0e10cSrcweir                 else
652*cdf0e10cSrcweir                     o << "        java.util.Hashtable fpm = "
653*cdf0e10cSrcweir                         "new java.util.Hashtable();\n";
654*cdf0e10cSrcweir             }
655*cdf0e10cSrcweir             bFirst = false;
656*cdf0e10cSrcweir         } else
657*cdf0e10cSrcweir             if ( options.language == 2 ) {
658*cdf0e10cSrcweir                 o << "        fpm = ParamMap();\n";
659*cdf0e10cSrcweir             }
660*cdf0e10cSrcweir             else {
661*cdf0e10cSrcweir                 if ( options.java5 )
662*cdf0e10cSrcweir                     o << "        fpm = new java.util.Hashtable< "
663*cdf0e10cSrcweir                         "Integer, String >();\n";
664*cdf0e10cSrcweir                 else
665*cdf0e10cSrcweir                     o << "        fpm = new java.util.Hashtable();\n";
666*cdf0e10cSrcweir             }
667*cdf0e10cSrcweir 
668*cdf0e10cSrcweir         for ( sal_uInt16 p = 0; p < reader.getMethodParameterCount(m); ++p ) {
669*cdf0e10cSrcweir             if ( options.language == 2 ) {
670*cdf0e10cSrcweir                 o << "        fpm[" << p
671*cdf0e10cSrcweir                   << "] = ::rtl::OUString::createFromAscii(\""
672*cdf0e10cSrcweir                   << codemaker::convertString(reader.getMethodParameterName(m, p))
673*cdf0e10cSrcweir                   << "\");\n";
674*cdf0e10cSrcweir             }
675*cdf0e10cSrcweir             else {
676*cdf0e10cSrcweir                 if ( options.java5 )
677*cdf0e10cSrcweir                     o << "        fpm.put(" << p << ", \""
678*cdf0e10cSrcweir                       << codemaker::convertString(
679*cdf0e10cSrcweir                           reader.getMethodParameterName(m, p))
680*cdf0e10cSrcweir                       << "\");\n";
681*cdf0e10cSrcweir                 else
682*cdf0e10cSrcweir                     o << "       fpm.put(new Integer(" << p << "), \""
683*cdf0e10cSrcweir                       << codemaker::convertString(
684*cdf0e10cSrcweir                           reader.getMethodParameterName(m, p))
685*cdf0e10cSrcweir                       << "\");\n";
686*cdf0e10cSrcweir             }
687*cdf0e10cSrcweir         }
688*cdf0e10cSrcweir 
689*cdf0e10cSrcweir         if ( options.language == 2 ) {
690*cdf0e10cSrcweir             o << "        m_functionMap[::rtl::OUString::createFromAscii(\""
691*cdf0e10cSrcweir               << sMethod << "\")] = fpm;\n\n";
692*cdf0e10cSrcweir         }
693*cdf0e10cSrcweir         else {
694*cdf0e10cSrcweir             o << "        m_functionMap.put(\"" << sMethod << "\", fpm);\n\n";
695*cdf0e10cSrcweir         }
696*cdf0e10cSrcweir     }
697*cdf0e10cSrcweir }
698*cdf0e10cSrcweir 
699*cdf0e10cSrcweir void generateFunctionParameterMap(std::ostream& o,
700*cdf0e10cSrcweir          ProgramOptions const & options,
701*cdf0e10cSrcweir          TypeManager const & manager,
702*cdf0e10cSrcweir          const std::hash_set< OString, OStringHash >& interfaces)
703*cdf0e10cSrcweir {
704*cdf0e10cSrcweir     ::codemaker::GeneratedTypeSet generated;
705*cdf0e10cSrcweir     bool bFirst = true;
706*cdf0e10cSrcweir     std::hash_set< OString, OStringHash >::const_iterator iter = interfaces.begin();
707*cdf0e10cSrcweir     while ( iter != interfaces.end() ) {
708*cdf0e10cSrcweir         typereg::Reader reader(manager.getTypeReader((*iter).replace('.','/')));
709*cdf0e10cSrcweir         if (!reader.isValid()) {
710*cdf0e10cSrcweir             throw CannotDumpException(
711*cdf0e10cSrcweir                 "Bad type library entity "
712*cdf0e10cSrcweir                 + codemaker::convertString(
713*cdf0e10cSrcweir                     reader.getTypeName()));
714*cdf0e10cSrcweir         }
715*cdf0e10cSrcweir 
716*cdf0e10cSrcweir         generateFunctionParamterMap(o, options, manager, reader, generated, bFirst);
717*cdf0e10cSrcweir         iter++;
718*cdf0e10cSrcweir     }
719*cdf0e10cSrcweir }
720*cdf0e10cSrcweir 
721*cdf0e10cSrcweir }
722*cdf0e10cSrcweir 
723