xref: /AOO41X/main/basic/source/runtime/methods.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 // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_basic.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir 
32*cdf0e10cSrcweir #include <tools/date.hxx>
33*cdf0e10cSrcweir #include <basic/sbxvar.hxx>
34*cdf0e10cSrcweir #ifndef _VOS_PROCESS_HXX
35*cdf0e10cSrcweir #include <vos/process.hxx>
36*cdf0e10cSrcweir #endif
37*cdf0e10cSrcweir #include <vcl/svapp.hxx>
38*cdf0e10cSrcweir #include <vcl/settings.hxx>
39*cdf0e10cSrcweir #include <vcl/sound.hxx>
40*cdf0e10cSrcweir #include <tools/wintypes.hxx>
41*cdf0e10cSrcweir #include <vcl/msgbox.hxx>
42*cdf0e10cSrcweir #include <basic/sbx.hxx>
43*cdf0e10cSrcweir #include <svl/zforlist.hxx>
44*cdf0e10cSrcweir #include <rtl/math.hxx>
45*cdf0e10cSrcweir #include <tools/urlobj.hxx>
46*cdf0e10cSrcweir #include <osl/time.h>
47*cdf0e10cSrcweir #include <unotools/charclass.hxx>
48*cdf0e10cSrcweir #include <unotools/ucbstreamhelper.hxx>
49*cdf0e10cSrcweir #include <tools/wldcrd.hxx>
50*cdf0e10cSrcweir #include <i18npool/lang.h>
51*cdf0e10cSrcweir 
52*cdf0e10cSrcweir #include "runtime.hxx"
53*cdf0e10cSrcweir #include "sbunoobj.hxx"
54*cdf0e10cSrcweir #ifdef WNT
55*cdf0e10cSrcweir #include <tools/prewin.h>
56*cdf0e10cSrcweir #include "winbase.h"
57*cdf0e10cSrcweir #include <tools/postwin.h>
58*cdf0e10cSrcweir #ifndef _FSYS_HXX //autogen
59*cdf0e10cSrcweir #include <tools/fsys.hxx>
60*cdf0e10cSrcweir #endif
61*cdf0e10cSrcweir #else
62*cdf0e10cSrcweir #include <osl/file.hxx>
63*cdf0e10cSrcweir #endif
64*cdf0e10cSrcweir #include "errobject.hxx"
65*cdf0e10cSrcweir 
66*cdf0e10cSrcweir #ifdef _USE_UNO
67*cdf0e10cSrcweir #include <comphelper/processfactory.hxx>
68*cdf0e10cSrcweir 
69*cdf0e10cSrcweir #include <com/sun/star/uno/Sequence.hxx>
70*cdf0e10cSrcweir #include <com/sun/star/util/DateTime.hpp>
71*cdf0e10cSrcweir #include <com/sun/star/lang/XMultiServiceFactory.hpp>
72*cdf0e10cSrcweir #include <com/sun/star/lang/Locale.hpp>
73*cdf0e10cSrcweir #include <com/sun/star/ucb/XSimpleFileAccess3.hpp>
74*cdf0e10cSrcweir #include <com/sun/star/io/XInputStream.hpp>
75*cdf0e10cSrcweir #include <com/sun/star/io/XOutputStream.hpp>
76*cdf0e10cSrcweir #include <com/sun/star/io/XStream.hpp>
77*cdf0e10cSrcweir #include <com/sun/star/io/XSeekable.hpp>
78*cdf0e10cSrcweir 
79*cdf0e10cSrcweir using namespace comphelper;
80*cdf0e10cSrcweir using namespace osl;
81*cdf0e10cSrcweir using namespace com::sun::star::uno;
82*cdf0e10cSrcweir using namespace com::sun::star::lang;
83*cdf0e10cSrcweir using namespace com::sun::star::ucb;
84*cdf0e10cSrcweir using namespace com::sun::star::io;
85*cdf0e10cSrcweir using namespace com::sun::star::frame;
86*cdf0e10cSrcweir 
87*cdf0e10cSrcweir #endif /* _USE_UNO */
88*cdf0e10cSrcweir 
89*cdf0e10cSrcweir //#define _ENABLE_CUR_DIR
90*cdf0e10cSrcweir 
91*cdf0e10cSrcweir #include "stdobj.hxx"
92*cdf0e10cSrcweir #include <basic/sbstdobj.hxx>
93*cdf0e10cSrcweir #include "rtlproto.hxx"
94*cdf0e10cSrcweir #include "basrid.hxx"
95*cdf0e10cSrcweir #include "image.hxx"
96*cdf0e10cSrcweir #include "sb.hrc"
97*cdf0e10cSrcweir #include "iosys.hxx"
98*cdf0e10cSrcweir #include "ddectrl.hxx"
99*cdf0e10cSrcweir #include <sbintern.hxx>
100*cdf0e10cSrcweir #include <basic/vbahelper.hxx>
101*cdf0e10cSrcweir 
102*cdf0e10cSrcweir #include <list>
103*cdf0e10cSrcweir #include <math.h>
104*cdf0e10cSrcweir #include <stdio.h>
105*cdf0e10cSrcweir #include <stdlib.h>
106*cdf0e10cSrcweir #include <ctype.h>
107*cdf0e10cSrcweir 
108*cdf0e10cSrcweir #if defined (WNT) || defined (OS2)
109*cdf0e10cSrcweir #include <direct.h>   // _getdcwd get current work directory, _chdrive
110*cdf0e10cSrcweir #endif
111*cdf0e10cSrcweir 
112*cdf0e10cSrcweir #ifdef UNX
113*cdf0e10cSrcweir #include <errno.h>
114*cdf0e10cSrcweir #include <unistd.h>
115*cdf0e10cSrcweir #endif
116*cdf0e10cSrcweir 
117*cdf0e10cSrcweir #ifdef WNT
118*cdf0e10cSrcweir #include <io.h>
119*cdf0e10cSrcweir #endif
120*cdf0e10cSrcweir 
121*cdf0e10cSrcweir #include <basic/sbobjmod.hxx>
122*cdf0e10cSrcweir 
123*cdf0e10cSrcweir // from source/classes/sbxmod.cxx
124*cdf0e10cSrcweir Reference< XModel > getDocumentModel( StarBASIC* );
125*cdf0e10cSrcweir 
126*cdf0e10cSrcweir static void FilterWhiteSpace( String& rStr )
127*cdf0e10cSrcweir {
128*cdf0e10cSrcweir 	rStr.EraseAllChars( ' ' );
129*cdf0e10cSrcweir 	rStr.EraseAllChars( '\t' );
130*cdf0e10cSrcweir 	rStr.EraseAllChars( '\n' );
131*cdf0e10cSrcweir 	rStr.EraseAllChars( '\r' );
132*cdf0e10cSrcweir }
133*cdf0e10cSrcweir 
134*cdf0e10cSrcweir static long GetDayDiff( const Date& rDate )
135*cdf0e10cSrcweir {
136*cdf0e10cSrcweir 	Date aRefDate( 1,1,1900 );
137*cdf0e10cSrcweir 	long nDiffDays;
138*cdf0e10cSrcweir 	if ( aRefDate > rDate )
139*cdf0e10cSrcweir 	{
140*cdf0e10cSrcweir 		nDiffDays = (long)(aRefDate - rDate);
141*cdf0e10cSrcweir 		nDiffDays *= -1;
142*cdf0e10cSrcweir 	}
143*cdf0e10cSrcweir 	else
144*cdf0e10cSrcweir 		nDiffDays = (long)(rDate - aRefDate);
145*cdf0e10cSrcweir 	nDiffDays += 2; // Anpassung VisualBasic: 1.Jan.1900 == 2
146*cdf0e10cSrcweir 	return nDiffDays;
147*cdf0e10cSrcweir }
148*cdf0e10cSrcweir 
149*cdf0e10cSrcweir static CharClass& GetCharClass( void )
150*cdf0e10cSrcweir {
151*cdf0e10cSrcweir 	static sal_Bool bNeedsInit = sal_True;
152*cdf0e10cSrcweir 	static ::com::sun::star::lang::Locale aLocale;
153*cdf0e10cSrcweir 	if( bNeedsInit )
154*cdf0e10cSrcweir 	{
155*cdf0e10cSrcweir         bNeedsInit = sal_False;
156*cdf0e10cSrcweir 		aLocale = Application::GetSettings().GetLocale();
157*cdf0e10cSrcweir 	}
158*cdf0e10cSrcweir 	static CharClass aCharClass( aLocale );
159*cdf0e10cSrcweir 	return aCharClass;
160*cdf0e10cSrcweir }
161*cdf0e10cSrcweir 
162*cdf0e10cSrcweir static inline sal_Bool isFolder( FileStatus::Type aType )
163*cdf0e10cSrcweir {
164*cdf0e10cSrcweir     return ( aType == FileStatus::Directory || aType == FileStatus::Volume );
165*cdf0e10cSrcweir }
166*cdf0e10cSrcweir 
167*cdf0e10cSrcweir 
168*cdf0e10cSrcweir //*** UCB file access ***
169*cdf0e10cSrcweir 
170*cdf0e10cSrcweir // Converts possibly relative paths to absolute paths
171*cdf0e10cSrcweir // according to the setting done by ChDir/ChDrive
172*cdf0e10cSrcweir String getFullPath( const String& aRelPath )
173*cdf0e10cSrcweir {
174*cdf0e10cSrcweir 	::rtl::OUString aFileURL;
175*cdf0e10cSrcweir 
176*cdf0e10cSrcweir 	// #80204 Try first if it already is a valid URL
177*cdf0e10cSrcweir 	INetURLObject aURLObj( aRelPath );
178*cdf0e10cSrcweir 	aFileURL = aURLObj.GetMainURL( INetURLObject::NO_DECODE );
179*cdf0e10cSrcweir 
180*cdf0e10cSrcweir 	if( !aFileURL.getLength() )
181*cdf0e10cSrcweir 	{
182*cdf0e10cSrcweir 		File::getFileURLFromSystemPath( aRelPath, aFileURL );
183*cdf0e10cSrcweir 	}
184*cdf0e10cSrcweir 
185*cdf0e10cSrcweir     return aFileURL;
186*cdf0e10cSrcweir }
187*cdf0e10cSrcweir 
188*cdf0e10cSrcweir // Sets (virtual) current path for UCB file access
189*cdf0e10cSrcweir void implChDir( const String& aDir )
190*cdf0e10cSrcweir {
191*cdf0e10cSrcweir     (void)aDir;
192*cdf0e10cSrcweir 	// TODO
193*cdf0e10cSrcweir }
194*cdf0e10cSrcweir 
195*cdf0e10cSrcweir // Sets (virtual) current drive for UCB file access
196*cdf0e10cSrcweir void implChDrive( const String& aDrive )
197*cdf0e10cSrcweir {
198*cdf0e10cSrcweir     (void)aDrive;
199*cdf0e10cSrcweir 	// TODO
200*cdf0e10cSrcweir }
201*cdf0e10cSrcweir 
202*cdf0e10cSrcweir // Returns (virtual) current path for UCB file access
203*cdf0e10cSrcweir String implGetCurDir( void )
204*cdf0e10cSrcweir {
205*cdf0e10cSrcweir 	String aRetStr;
206*cdf0e10cSrcweir 
207*cdf0e10cSrcweir 	return aRetStr;
208*cdf0e10cSrcweir }
209*cdf0e10cSrcweir 
210*cdf0e10cSrcweir // TODO: -> SbiGlobals
211*cdf0e10cSrcweir static com::sun::star::uno::Reference< XSimpleFileAccess3 > getFileAccess( void )
212*cdf0e10cSrcweir {
213*cdf0e10cSrcweir 	static com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI;
214*cdf0e10cSrcweir 	if( !xSFI.is() )
215*cdf0e10cSrcweir 	{
216*cdf0e10cSrcweir 		com::sun::star::uno::Reference< XMultiServiceFactory > xSMgr = getProcessServiceFactory();
217*cdf0e10cSrcweir 		if( xSMgr.is() )
218*cdf0e10cSrcweir 		{
219*cdf0e10cSrcweir 			xSFI = com::sun::star::uno::Reference< XSimpleFileAccess3 >( xSMgr->createInstance
220*cdf0e10cSrcweir 				( ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY );
221*cdf0e10cSrcweir 		}
222*cdf0e10cSrcweir 	}
223*cdf0e10cSrcweir 	return xSFI;
224*cdf0e10cSrcweir }
225*cdf0e10cSrcweir 
226*cdf0e10cSrcweir 
227*cdf0e10cSrcweir 
228*cdf0e10cSrcweir // Properties und Methoden legen beim Get (bPut = sal_False) den Returnwert
229*cdf0e10cSrcweir // im Element 0 des Argv ab; beim Put (bPut = sal_True) wird der Wert aus
230*cdf0e10cSrcweir // Element 0 gespeichert.
231*cdf0e10cSrcweir 
232*cdf0e10cSrcweir // CreateObject( class )
233*cdf0e10cSrcweir 
234*cdf0e10cSrcweir RTLFUNC(CreateObject)
235*cdf0e10cSrcweir {
236*cdf0e10cSrcweir     (void)bWrite;
237*cdf0e10cSrcweir 
238*cdf0e10cSrcweir 	String aClass( rPar.Get( 1 )->GetString() );
239*cdf0e10cSrcweir 	SbxObjectRef p = SbxBase::CreateObject( aClass );
240*cdf0e10cSrcweir 	if( !p )
241*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_CANNOT_LOAD );
242*cdf0e10cSrcweir 	else
243*cdf0e10cSrcweir 	{
244*cdf0e10cSrcweir 		// Convenience: BASIC als Parent eintragen
245*cdf0e10cSrcweir 		p->SetParent( pBasic );
246*cdf0e10cSrcweir 		rPar.Get( 0 )->PutObject( p );
247*cdf0e10cSrcweir 	}
248*cdf0e10cSrcweir }
249*cdf0e10cSrcweir 
250*cdf0e10cSrcweir // Error( n )
251*cdf0e10cSrcweir 
252*cdf0e10cSrcweir RTLFUNC(Error)
253*cdf0e10cSrcweir {
254*cdf0e10cSrcweir     (void)bWrite;
255*cdf0e10cSrcweir 
256*cdf0e10cSrcweir 	if( !pBasic )
257*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_INTERNAL_ERROR );
258*cdf0e10cSrcweir 	else
259*cdf0e10cSrcweir 	{
260*cdf0e10cSrcweir 		String aErrorMsg;
261*cdf0e10cSrcweir 		SbError nErr = 0L;
262*cdf0e10cSrcweir 		sal_Int32 nCode = 0;
263*cdf0e10cSrcweir 		if( rPar.Count() == 1 )
264*cdf0e10cSrcweir 		{
265*cdf0e10cSrcweir 			nErr = StarBASIC::GetErrBasic();
266*cdf0e10cSrcweir 			aErrorMsg = StarBASIC::GetErrorMsg();
267*cdf0e10cSrcweir 		}
268*cdf0e10cSrcweir 		else
269*cdf0e10cSrcweir 		{
270*cdf0e10cSrcweir 			nCode = rPar.Get( 1 )->GetLong();
271*cdf0e10cSrcweir 			if( nCode > 65535L )
272*cdf0e10cSrcweir 				StarBASIC::Error( SbERR_CONVERSION );
273*cdf0e10cSrcweir 			else
274*cdf0e10cSrcweir 				nErr = StarBASIC::GetSfxFromVBError( (sal_uInt16)nCode );
275*cdf0e10cSrcweir 		}
276*cdf0e10cSrcweir 
277*cdf0e10cSrcweir 		bool bVBA = SbiRuntime::isVBAEnabled();
278*cdf0e10cSrcweir 		String tmpErrMsg;
279*cdf0e10cSrcweir 		if( bVBA && aErrorMsg.Len() > 0 )
280*cdf0e10cSrcweir 		{
281*cdf0e10cSrcweir 			tmpErrMsg = aErrorMsg;
282*cdf0e10cSrcweir 		}
283*cdf0e10cSrcweir 		else
284*cdf0e10cSrcweir 		{
285*cdf0e10cSrcweir 			pBasic->MakeErrorText( nErr, aErrorMsg );
286*cdf0e10cSrcweir 			tmpErrMsg = pBasic->GetErrorText();
287*cdf0e10cSrcweir 		}
288*cdf0e10cSrcweir 		// If this rtlfunc 'Error'  passed a errcode the same as the active Err Objects's
289*cdf0e10cSrcweir 		// current err then  return the description for the error message if it is set
290*cdf0e10cSrcweir 		// ( complicated isn't it ? )
291*cdf0e10cSrcweir 		if ( bVBA && rPar.Count() > 1 )
292*cdf0e10cSrcweir 		{
293*cdf0e10cSrcweir 			com::sun::star::uno::Reference< ooo::vba::XErrObject > xErrObj( SbxErrObject::getUnoErrObject() );
294*cdf0e10cSrcweir 			if ( xErrObj.is() && xErrObj->getNumber() == nCode && xErrObj->getDescription().getLength() )
295*cdf0e10cSrcweir 				tmpErrMsg = xErrObj->getDescription();
296*cdf0e10cSrcweir 		}
297*cdf0e10cSrcweir 		rPar.Get( 0 )->PutString( tmpErrMsg );
298*cdf0e10cSrcweir 	}
299*cdf0e10cSrcweir }
300*cdf0e10cSrcweir 
301*cdf0e10cSrcweir // Sinus
302*cdf0e10cSrcweir 
303*cdf0e10cSrcweir RTLFUNC(Sin)
304*cdf0e10cSrcweir {
305*cdf0e10cSrcweir     (void)pBasic;
306*cdf0e10cSrcweir     (void)bWrite;
307*cdf0e10cSrcweir 
308*cdf0e10cSrcweir 	if ( rPar.Count() < 2 )
309*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
310*cdf0e10cSrcweir 	else
311*cdf0e10cSrcweir 	{
312*cdf0e10cSrcweir 		SbxVariableRef pArg = rPar.Get( 1 );
313*cdf0e10cSrcweir 		rPar.Get( 0 )->PutDouble( sin( pArg->GetDouble() ) );
314*cdf0e10cSrcweir 	}
315*cdf0e10cSrcweir }
316*cdf0e10cSrcweir 
317*cdf0e10cSrcweir // Cosinus
318*cdf0e10cSrcweir 
319*cdf0e10cSrcweir RTLFUNC(Cos)
320*cdf0e10cSrcweir {
321*cdf0e10cSrcweir     (void)pBasic;
322*cdf0e10cSrcweir     (void)bWrite;
323*cdf0e10cSrcweir 
324*cdf0e10cSrcweir 	if ( rPar.Count() < 2 )
325*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
326*cdf0e10cSrcweir 	else
327*cdf0e10cSrcweir 	{
328*cdf0e10cSrcweir 		SbxVariableRef pArg = rPar.Get( 1 );
329*cdf0e10cSrcweir 		rPar.Get( 0 )->PutDouble( cos( pArg->GetDouble() ) );
330*cdf0e10cSrcweir 	}
331*cdf0e10cSrcweir }
332*cdf0e10cSrcweir 
333*cdf0e10cSrcweir // Atn
334*cdf0e10cSrcweir 
335*cdf0e10cSrcweir RTLFUNC(Atn)
336*cdf0e10cSrcweir {
337*cdf0e10cSrcweir     (void)pBasic;
338*cdf0e10cSrcweir     (void)bWrite;
339*cdf0e10cSrcweir 
340*cdf0e10cSrcweir 	if ( rPar.Count() < 2 )
341*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
342*cdf0e10cSrcweir 	else
343*cdf0e10cSrcweir 	{
344*cdf0e10cSrcweir 		SbxVariableRef pArg = rPar.Get( 1 );
345*cdf0e10cSrcweir 		rPar.Get( 0 )->PutDouble( atan( pArg->GetDouble() ) );
346*cdf0e10cSrcweir 	}
347*cdf0e10cSrcweir }
348*cdf0e10cSrcweir 
349*cdf0e10cSrcweir 
350*cdf0e10cSrcweir 
351*cdf0e10cSrcweir RTLFUNC(Abs)
352*cdf0e10cSrcweir {
353*cdf0e10cSrcweir     (void)pBasic;
354*cdf0e10cSrcweir     (void)bWrite;
355*cdf0e10cSrcweir 
356*cdf0e10cSrcweir 	if ( rPar.Count() < 2 )
357*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
358*cdf0e10cSrcweir 	else
359*cdf0e10cSrcweir 	{
360*cdf0e10cSrcweir 		SbxVariableRef pArg = rPar.Get( 1 );
361*cdf0e10cSrcweir 		rPar.Get( 0 )->PutDouble( fabs( pArg->GetDouble() ) );
362*cdf0e10cSrcweir 	}
363*cdf0e10cSrcweir }
364*cdf0e10cSrcweir 
365*cdf0e10cSrcweir 
366*cdf0e10cSrcweir RTLFUNC(Asc)
367*cdf0e10cSrcweir {
368*cdf0e10cSrcweir     (void)pBasic;
369*cdf0e10cSrcweir     (void)bWrite;
370*cdf0e10cSrcweir 
371*cdf0e10cSrcweir 	if ( rPar.Count() < 2 )
372*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
373*cdf0e10cSrcweir 	else
374*cdf0e10cSrcweir 	{
375*cdf0e10cSrcweir 		SbxVariableRef pArg = rPar.Get( 1 );
376*cdf0e10cSrcweir 		String aStr( pArg->GetString() );
377*cdf0e10cSrcweir 		if ( aStr.Len() == 0 )
378*cdf0e10cSrcweir 		{
379*cdf0e10cSrcweir 			StarBASIC::Error( SbERR_BAD_ARGUMENT );
380*cdf0e10cSrcweir 			rPar.Get(0)->PutEmpty();
381*cdf0e10cSrcweir 		}
382*cdf0e10cSrcweir 		else
383*cdf0e10cSrcweir 		{
384*cdf0e10cSrcweir 			sal_Unicode aCh = aStr.GetBuffer()[0];
385*cdf0e10cSrcweir 			rPar.Get(0)->PutLong( aCh );
386*cdf0e10cSrcweir 		}
387*cdf0e10cSrcweir 	}
388*cdf0e10cSrcweir }
389*cdf0e10cSrcweir 
390*cdf0e10cSrcweir void implChr( SbxArray& rPar, bool bChrW )
391*cdf0e10cSrcweir {
392*cdf0e10cSrcweir 	if ( rPar.Count() < 2 )
393*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
394*cdf0e10cSrcweir 	else
395*cdf0e10cSrcweir 	{
396*cdf0e10cSrcweir 		SbxVariableRef pArg = rPar.Get( 1 );
397*cdf0e10cSrcweir 
398*cdf0e10cSrcweir 		String aStr;
399*cdf0e10cSrcweir 		if( !bChrW && SbiRuntime::isVBAEnabled() )
400*cdf0e10cSrcweir 		{
401*cdf0e10cSrcweir 			sal_Char c = (sal_Char)pArg->GetByte();
402*cdf0e10cSrcweir 			ByteString s( c );
403*cdf0e10cSrcweir 			aStr = String( s, gsl_getSystemTextEncoding() );
404*cdf0e10cSrcweir 		}
405*cdf0e10cSrcweir 		else
406*cdf0e10cSrcweir 		{
407*cdf0e10cSrcweir 			sal_Unicode aCh = (sal_Unicode)pArg->GetUShort();
408*cdf0e10cSrcweir 			aStr = String( aCh );
409*cdf0e10cSrcweir 		}
410*cdf0e10cSrcweir 		rPar.Get(0)->PutString( aStr );
411*cdf0e10cSrcweir 	}
412*cdf0e10cSrcweir }
413*cdf0e10cSrcweir 
414*cdf0e10cSrcweir RTLFUNC(Chr)
415*cdf0e10cSrcweir {
416*cdf0e10cSrcweir     (void)pBasic;
417*cdf0e10cSrcweir     (void)bWrite;
418*cdf0e10cSrcweir 
419*cdf0e10cSrcweir 	bool bChrW = false;
420*cdf0e10cSrcweir 	implChr( rPar, bChrW );
421*cdf0e10cSrcweir }
422*cdf0e10cSrcweir 
423*cdf0e10cSrcweir RTLFUNC(ChrW)
424*cdf0e10cSrcweir {
425*cdf0e10cSrcweir     (void)pBasic;
426*cdf0e10cSrcweir     (void)bWrite;
427*cdf0e10cSrcweir 
428*cdf0e10cSrcweir 	bool bChrW = true;
429*cdf0e10cSrcweir 	implChr( rPar, bChrW );
430*cdf0e10cSrcweir }
431*cdf0e10cSrcweir 
432*cdf0e10cSrcweir 
433*cdf0e10cSrcweir #ifdef UNX
434*cdf0e10cSrcweir #define _MAX_PATH 260
435*cdf0e10cSrcweir #define _PATH_INCR 250
436*cdf0e10cSrcweir #endif
437*cdf0e10cSrcweir 
438*cdf0e10cSrcweir RTLFUNC(CurDir)
439*cdf0e10cSrcweir {
440*cdf0e10cSrcweir     (void)pBasic;
441*cdf0e10cSrcweir     (void)bWrite;
442*cdf0e10cSrcweir 
443*cdf0e10cSrcweir 	// #57064 Obwohl diese Funktion nicht mit DirEntry arbeitet, ist sie von
444*cdf0e10cSrcweir 	// der Anpassung an virtuelle URLs nich betroffen, da bei Nutzung der
445*cdf0e10cSrcweir 	// DirEntry-Funktionalitaet keine Moeglichkeit besteht, das aktuelle so
446*cdf0e10cSrcweir 	// zu ermitteln, dass eine virtuelle URL geliefert werden koennte.
447*cdf0e10cSrcweir 
448*cdf0e10cSrcweir //	rPar.Get(0)->PutEmpty();
449*cdf0e10cSrcweir #if defined (WNT) || defined (OS2)
450*cdf0e10cSrcweir 	int nCurDir = 0;  // Current dir // JSM
451*cdf0e10cSrcweir 	if ( rPar.Count() == 2 )
452*cdf0e10cSrcweir 	{
453*cdf0e10cSrcweir 		String aDrive = rPar.Get(1)->GetString();
454*cdf0e10cSrcweir 		if ( aDrive.Len() != 1 )
455*cdf0e10cSrcweir 		{
456*cdf0e10cSrcweir 			StarBASIC::Error( SbERR_BAD_ARGUMENT );
457*cdf0e10cSrcweir 			return;
458*cdf0e10cSrcweir 		}
459*cdf0e10cSrcweir 		else
460*cdf0e10cSrcweir 		{
461*cdf0e10cSrcweir 			nCurDir = (int)aDrive.GetBuffer()[0];
462*cdf0e10cSrcweir 			if ( !isalpha( nCurDir ) )
463*cdf0e10cSrcweir 			{
464*cdf0e10cSrcweir 				StarBASIC::Error( SbERR_BAD_ARGUMENT );
465*cdf0e10cSrcweir 				return;
466*cdf0e10cSrcweir 			}
467*cdf0e10cSrcweir 			else
468*cdf0e10cSrcweir 				nCurDir -= ( 'A' - 1 );
469*cdf0e10cSrcweir 		}
470*cdf0e10cSrcweir 	}
471*cdf0e10cSrcweir 	char* pBuffer = new char[ _MAX_PATH ];
472*cdf0e10cSrcweir #ifdef OS2
473*cdf0e10cSrcweir 	if( !nCurDir )
474*cdf0e10cSrcweir 		nCurDir = _getdrive();
475*cdf0e10cSrcweir #endif
476*cdf0e10cSrcweir 	if ( _getdcwd( nCurDir, pBuffer, _MAX_PATH ) != 0 )
477*cdf0e10cSrcweir 		rPar.Get(0)->PutString( String::CreateFromAscii( pBuffer ) );
478*cdf0e10cSrcweir 	else
479*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_NO_DEVICE );
480*cdf0e10cSrcweir 	delete [] pBuffer;
481*cdf0e10cSrcweir 
482*cdf0e10cSrcweir #elif defined( UNX )
483*cdf0e10cSrcweir 
484*cdf0e10cSrcweir 	int nSize = _PATH_INCR;
485*cdf0e10cSrcweir 	char* pMem;
486*cdf0e10cSrcweir 	while( sal_True )
487*cdf0e10cSrcweir 	  {
488*cdf0e10cSrcweir 		pMem = new char[nSize];
489*cdf0e10cSrcweir 		if( !pMem )
490*cdf0e10cSrcweir 		  {
491*cdf0e10cSrcweir 			StarBASIC::Error( SbERR_NO_MEMORY );
492*cdf0e10cSrcweir 			return;
493*cdf0e10cSrcweir 		  }
494*cdf0e10cSrcweir 		if( getcwd( pMem, nSize-1 ) != NULL )
495*cdf0e10cSrcweir 		  {
496*cdf0e10cSrcweir 			rPar.Get(0)->PutString( String::CreateFromAscii(pMem) );
497*cdf0e10cSrcweir 			delete [] pMem;
498*cdf0e10cSrcweir 			return;
499*cdf0e10cSrcweir 		  }
500*cdf0e10cSrcweir 		if( errno != ERANGE )
501*cdf0e10cSrcweir 		  {
502*cdf0e10cSrcweir 			StarBASIC::Error( SbERR_INTERNAL_ERROR );
503*cdf0e10cSrcweir 			delete [] pMem;
504*cdf0e10cSrcweir 			return;
505*cdf0e10cSrcweir 		  }
506*cdf0e10cSrcweir 		delete [] pMem;
507*cdf0e10cSrcweir 		nSize += _PATH_INCR;
508*cdf0e10cSrcweir 	  };
509*cdf0e10cSrcweir 
510*cdf0e10cSrcweir #endif
511*cdf0e10cSrcweir }
512*cdf0e10cSrcweir 
513*cdf0e10cSrcweir RTLFUNC(ChDir) // JSM
514*cdf0e10cSrcweir {
515*cdf0e10cSrcweir     (void)bWrite;
516*cdf0e10cSrcweir 
517*cdf0e10cSrcweir 	rPar.Get(0)->PutEmpty();
518*cdf0e10cSrcweir 	if (rPar.Count() == 2)
519*cdf0e10cSrcweir 	{
520*cdf0e10cSrcweir #ifdef _ENABLE_CUR_DIR
521*cdf0e10cSrcweir 		String aPath = rPar.Get(1)->GetString();
522*cdf0e10cSrcweir 		sal_Bool bError = sal_False;
523*cdf0e10cSrcweir #ifdef WNT
524*cdf0e10cSrcweir 		// #55997 Laut MI hilft es bei File-URLs einen DirEntry zwischenzuschalten
525*cdf0e10cSrcweir 		// #40996 Harmoniert bei Verwendung der WIN32-Funktion nicht mit getdir
526*cdf0e10cSrcweir 		DirEntry aEntry( aPath );
527*cdf0e10cSrcweir 		ByteString aFullPath( aEntry.GetFull(), gsl_getSystemTextEncoding() );
528*cdf0e10cSrcweir 		if( chdir( aFullPath.GetBuffer()) )
529*cdf0e10cSrcweir 			bError = sal_True;
530*cdf0e10cSrcweir #else
531*cdf0e10cSrcweir 		if (!DirEntry(aPath).SetCWD())
532*cdf0e10cSrcweir 			bError = sal_True;
533*cdf0e10cSrcweir #endif
534*cdf0e10cSrcweir 		if( bError )
535*cdf0e10cSrcweir 			StarBASIC::Error( SbERR_PATH_NOT_FOUND );
536*cdf0e10cSrcweir #endif
537*cdf0e10cSrcweir         // VBA: track current directory per document type (separately for Writer, Calc, Impress, etc.)
538*cdf0e10cSrcweir         if( SbiRuntime::isVBAEnabled() )
539*cdf0e10cSrcweir             ::basic::vba::registerCurrentDirectory( getDocumentModel( pBasic ), rPar.Get(1)->GetString() );
540*cdf0e10cSrcweir 	}
541*cdf0e10cSrcweir 	else
542*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
543*cdf0e10cSrcweir }
544*cdf0e10cSrcweir 
545*cdf0e10cSrcweir RTLFUNC(ChDrive) // JSM
546*cdf0e10cSrcweir {
547*cdf0e10cSrcweir     (void)pBasic;
548*cdf0e10cSrcweir     (void)bWrite;
549*cdf0e10cSrcweir 
550*cdf0e10cSrcweir 	rPar.Get(0)->PutEmpty();
551*cdf0e10cSrcweir 	if (rPar.Count() == 2)
552*cdf0e10cSrcweir 	{
553*cdf0e10cSrcweir #ifdef _ENABLE_CUR_DIR
554*cdf0e10cSrcweir 		// Keine Laufwerke in Unix
555*cdf0e10cSrcweir #ifndef UNX
556*cdf0e10cSrcweir 		String aPar1 = rPar.Get(1)->GetString();
557*cdf0e10cSrcweir 
558*cdf0e10cSrcweir #if defined (WNT) || defined (OS2)
559*cdf0e10cSrcweir 		if (aPar1.Len() > 0)
560*cdf0e10cSrcweir 		{
561*cdf0e10cSrcweir 			int nCurDrive = (int)aPar1.GetBuffer()[0]; ;
562*cdf0e10cSrcweir 			if ( !isalpha( nCurDrive ) )
563*cdf0e10cSrcweir 			{
564*cdf0e10cSrcweir 				StarBASIC::Error( SbERR_BAD_ARGUMENT );
565*cdf0e10cSrcweir 				return;
566*cdf0e10cSrcweir 			}
567*cdf0e10cSrcweir 			else
568*cdf0e10cSrcweir 				nCurDrive -= ( 'A' - 1 );
569*cdf0e10cSrcweir 			if (_chdrive(nCurDrive))
570*cdf0e10cSrcweir 				StarBASIC::Error( SbERR_NO_DEVICE );
571*cdf0e10cSrcweir 		}
572*cdf0e10cSrcweir #endif
573*cdf0e10cSrcweir 
574*cdf0e10cSrcweir #endif
575*cdf0e10cSrcweir 		// #ifndef UNX
576*cdf0e10cSrcweir #endif
577*cdf0e10cSrcweir 	}
578*cdf0e10cSrcweir 	else
579*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
580*cdf0e10cSrcweir }
581*cdf0e10cSrcweir 
582*cdf0e10cSrcweir 
583*cdf0e10cSrcweir // Implementation of StepRENAME with UCB
584*cdf0e10cSrcweir void implStepRenameUCB( const String& aSource, const String& aDest )
585*cdf0e10cSrcweir {
586*cdf0e10cSrcweir 	com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess();
587*cdf0e10cSrcweir 	if( xSFI.is() )
588*cdf0e10cSrcweir 	{
589*cdf0e10cSrcweir 		try
590*cdf0e10cSrcweir 		{
591*cdf0e10cSrcweir 			String aSourceFullPath = getFullPath( aSource );
592*cdf0e10cSrcweir 			if( !xSFI->exists( aSourceFullPath ) )
593*cdf0e10cSrcweir 			{
594*cdf0e10cSrcweir 				StarBASIC::Error( SbERR_FILE_NOT_FOUND );
595*cdf0e10cSrcweir 				return;
596*cdf0e10cSrcweir 			}
597*cdf0e10cSrcweir 
598*cdf0e10cSrcweir 			String aDestFullPath = getFullPath( aDest );
599*cdf0e10cSrcweir 			if( xSFI->exists( aDestFullPath ) )
600*cdf0e10cSrcweir 				StarBASIC::Error( SbERR_FILE_EXISTS );
601*cdf0e10cSrcweir 			else
602*cdf0e10cSrcweir 				xSFI->move( aSourceFullPath, aDestFullPath );
603*cdf0e10cSrcweir 		}
604*cdf0e10cSrcweir 		catch( Exception & )
605*cdf0e10cSrcweir 		{
606*cdf0e10cSrcweir 			StarBASIC::Error( SbERR_FILE_NOT_FOUND );
607*cdf0e10cSrcweir 		}
608*cdf0e10cSrcweir 	}
609*cdf0e10cSrcweir }
610*cdf0e10cSrcweir 
611*cdf0e10cSrcweir // Implementation of StepRENAME with OSL
612*cdf0e10cSrcweir void implStepRenameOSL( const String& aSource, const String& aDest )
613*cdf0e10cSrcweir {
614*cdf0e10cSrcweir 	FileBase::RC nRet = File::move( getFullPathUNC( aSource ), getFullPathUNC( aDest ) );
615*cdf0e10cSrcweir 	if( nRet != FileBase::E_None )
616*cdf0e10cSrcweir 	{
617*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_PATH_NOT_FOUND );
618*cdf0e10cSrcweir 	}
619*cdf0e10cSrcweir }
620*cdf0e10cSrcweir 
621*cdf0e10cSrcweir RTLFUNC(FileCopy) // JSM
622*cdf0e10cSrcweir {
623*cdf0e10cSrcweir     (void)pBasic;
624*cdf0e10cSrcweir     (void)bWrite;
625*cdf0e10cSrcweir 
626*cdf0e10cSrcweir 	rPar.Get(0)->PutEmpty();
627*cdf0e10cSrcweir 	if (rPar.Count() == 3)
628*cdf0e10cSrcweir 	{
629*cdf0e10cSrcweir 		String aSource = rPar.Get(1)->GetString();
630*cdf0e10cSrcweir 		String aDest = rPar.Get(2)->GetString();
631*cdf0e10cSrcweir 		// <-- UCB
632*cdf0e10cSrcweir 		if( hasUno() )
633*cdf0e10cSrcweir 		{
634*cdf0e10cSrcweir 			com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess();
635*cdf0e10cSrcweir 			if( xSFI.is() )
636*cdf0e10cSrcweir 			{
637*cdf0e10cSrcweir 				try
638*cdf0e10cSrcweir 				{
639*cdf0e10cSrcweir 					xSFI->copy( getFullPath( aSource ), getFullPath( aDest ) );
640*cdf0e10cSrcweir 				}
641*cdf0e10cSrcweir 				catch( Exception & )
642*cdf0e10cSrcweir 				{
643*cdf0e10cSrcweir 					StarBASIC::Error( SbERR_PATH_NOT_FOUND );
644*cdf0e10cSrcweir 				}
645*cdf0e10cSrcweir 			}
646*cdf0e10cSrcweir 		}
647*cdf0e10cSrcweir 		else
648*cdf0e10cSrcweir 		// --> UCB
649*cdf0e10cSrcweir 		{
650*cdf0e10cSrcweir #ifdef _OLD_FILE_IMPL
651*cdf0e10cSrcweir 			DirEntry aSourceDirEntry(aSource);
652*cdf0e10cSrcweir 			if (aSourceDirEntry.Exists())
653*cdf0e10cSrcweir 			{
654*cdf0e10cSrcweir 				if (aSourceDirEntry.CopyTo(DirEntry(aDest),FSYS_ACTION_COPYFILE) != FSYS_ERR_OK)
655*cdf0e10cSrcweir 					StarBASIC::Error( SbERR_PATH_NOT_FOUND );
656*cdf0e10cSrcweir 			}
657*cdf0e10cSrcweir 			else
658*cdf0e10cSrcweir 					StarBASIC::Error( SbERR_PATH_NOT_FOUND );
659*cdf0e10cSrcweir #else
660*cdf0e10cSrcweir 			FileBase::RC nRet = File::copy( getFullPathUNC( aSource ), getFullPathUNC( aDest ) );
661*cdf0e10cSrcweir 			if( nRet != FileBase::E_None )
662*cdf0e10cSrcweir 			{
663*cdf0e10cSrcweir 				StarBASIC::Error( SbERR_PATH_NOT_FOUND );
664*cdf0e10cSrcweir 			}
665*cdf0e10cSrcweir #endif
666*cdf0e10cSrcweir 		}
667*cdf0e10cSrcweir 	}
668*cdf0e10cSrcweir 	else
669*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
670*cdf0e10cSrcweir }
671*cdf0e10cSrcweir 
672*cdf0e10cSrcweir RTLFUNC(Kill) // JSM
673*cdf0e10cSrcweir {
674*cdf0e10cSrcweir     (void)pBasic;
675*cdf0e10cSrcweir     (void)bWrite;
676*cdf0e10cSrcweir 
677*cdf0e10cSrcweir 	rPar.Get(0)->PutEmpty();
678*cdf0e10cSrcweir 	if (rPar.Count() == 2)
679*cdf0e10cSrcweir 	{
680*cdf0e10cSrcweir 		String aFileSpec = rPar.Get(1)->GetString();
681*cdf0e10cSrcweir 
682*cdf0e10cSrcweir 		// <-- UCB
683*cdf0e10cSrcweir 		if( hasUno() )
684*cdf0e10cSrcweir 		{
685*cdf0e10cSrcweir 			com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess();
686*cdf0e10cSrcweir 			if( xSFI.is() )
687*cdf0e10cSrcweir 			{
688*cdf0e10cSrcweir 			    String aFullPath = getFullPath( aFileSpec );
689*cdf0e10cSrcweir 				if( !xSFI->exists( aFullPath ) || xSFI->isFolder( aFullPath ) )
690*cdf0e10cSrcweir 				{
691*cdf0e10cSrcweir 					StarBASIC::Error( SbERR_FILE_NOT_FOUND );
692*cdf0e10cSrcweir 					return;
693*cdf0e10cSrcweir 				}
694*cdf0e10cSrcweir 				try
695*cdf0e10cSrcweir 				{
696*cdf0e10cSrcweir 					xSFI->kill( aFullPath );
697*cdf0e10cSrcweir 				}
698*cdf0e10cSrcweir 				catch( Exception & )
699*cdf0e10cSrcweir 				{
700*cdf0e10cSrcweir 					StarBASIC::Error( ERRCODE_IO_GENERAL );
701*cdf0e10cSrcweir 				}
702*cdf0e10cSrcweir 			}
703*cdf0e10cSrcweir 		}
704*cdf0e10cSrcweir 		else
705*cdf0e10cSrcweir 		// --> UCB
706*cdf0e10cSrcweir 		{
707*cdf0e10cSrcweir #ifdef _OLD_FILE_IMPL
708*cdf0e10cSrcweir 			if(DirEntry(aFileSpec).Kill() != FSYS_ERR_OK)
709*cdf0e10cSrcweir 				StarBASIC::Error( SbERR_PATH_NOT_FOUND );
710*cdf0e10cSrcweir #else
711*cdf0e10cSrcweir 			File::remove( getFullPathUNC( aFileSpec ) );
712*cdf0e10cSrcweir #endif
713*cdf0e10cSrcweir 		}
714*cdf0e10cSrcweir 	}
715*cdf0e10cSrcweir 	else
716*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
717*cdf0e10cSrcweir }
718*cdf0e10cSrcweir 
719*cdf0e10cSrcweir RTLFUNC(MkDir) // JSM
720*cdf0e10cSrcweir {
721*cdf0e10cSrcweir     (void)pBasic;
722*cdf0e10cSrcweir     (void)bWrite;
723*cdf0e10cSrcweir 
724*cdf0e10cSrcweir 	rPar.Get(0)->PutEmpty();
725*cdf0e10cSrcweir 	if (rPar.Count() == 2)
726*cdf0e10cSrcweir 	{
727*cdf0e10cSrcweir 		String aPath = rPar.Get(1)->GetString();
728*cdf0e10cSrcweir 
729*cdf0e10cSrcweir 		// <-- UCB
730*cdf0e10cSrcweir 		if( hasUno() )
731*cdf0e10cSrcweir 		{
732*cdf0e10cSrcweir 			com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess();
733*cdf0e10cSrcweir 			if( xSFI.is() )
734*cdf0e10cSrcweir 			{
735*cdf0e10cSrcweir 				try
736*cdf0e10cSrcweir 				{
737*cdf0e10cSrcweir 					xSFI->createFolder( getFullPath( aPath ) );
738*cdf0e10cSrcweir 				}
739*cdf0e10cSrcweir 				catch( Exception & )
740*cdf0e10cSrcweir 				{
741*cdf0e10cSrcweir 					StarBASIC::Error( ERRCODE_IO_GENERAL );
742*cdf0e10cSrcweir 				}
743*cdf0e10cSrcweir 			}
744*cdf0e10cSrcweir 		}
745*cdf0e10cSrcweir 		else
746*cdf0e10cSrcweir 		// --> UCB
747*cdf0e10cSrcweir 		{
748*cdf0e10cSrcweir #ifdef _OLD_FILE_IMPL
749*cdf0e10cSrcweir 			if (!DirEntry(aPath).MakeDir())
750*cdf0e10cSrcweir 				StarBASIC::Error( SbERR_PATH_NOT_FOUND );
751*cdf0e10cSrcweir #else
752*cdf0e10cSrcweir 			Directory::create( getFullPathUNC( aPath ) );
753*cdf0e10cSrcweir #endif
754*cdf0e10cSrcweir 		}
755*cdf0e10cSrcweir 	}
756*cdf0e10cSrcweir 	else
757*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
758*cdf0e10cSrcweir }
759*cdf0e10cSrcweir 
760*cdf0e10cSrcweir 
761*cdf0e10cSrcweir #ifndef _OLD_FILE_IMPL
762*cdf0e10cSrcweir 
763*cdf0e10cSrcweir // In OSL only empty directories can be deleted
764*cdf0e10cSrcweir // so we have to delete all files recursively
765*cdf0e10cSrcweir void implRemoveDirRecursive( const String& aDirPath )
766*cdf0e10cSrcweir {
767*cdf0e10cSrcweir 	DirectoryItem aItem;
768*cdf0e10cSrcweir 	FileBase::RC nRet = DirectoryItem::get( aDirPath, aItem );
769*cdf0e10cSrcweir 	sal_Bool bExists = (nRet == FileBase::E_None);
770*cdf0e10cSrcweir 
771*cdf0e10cSrcweir 	FileStatus aFileStatus( FileStatusMask_Type );
772*cdf0e10cSrcweir 	nRet = aItem.getFileStatus( aFileStatus );
773*cdf0e10cSrcweir 	FileStatus::Type aType = aFileStatus.getFileType();
774*cdf0e10cSrcweir 	sal_Bool bFolder = isFolder( aType );
775*cdf0e10cSrcweir 
776*cdf0e10cSrcweir 	if( !bExists || !bFolder )
777*cdf0e10cSrcweir 	{
778*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_PATH_NOT_FOUND );
779*cdf0e10cSrcweir 		return;
780*cdf0e10cSrcweir 	}
781*cdf0e10cSrcweir 
782*cdf0e10cSrcweir 	Directory aDir( aDirPath );
783*cdf0e10cSrcweir 	nRet = aDir.open();
784*cdf0e10cSrcweir 	if( nRet != FileBase::E_None )
785*cdf0e10cSrcweir 	{
786*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_PATH_NOT_FOUND );
787*cdf0e10cSrcweir 		return;
788*cdf0e10cSrcweir 	}
789*cdf0e10cSrcweir 
790*cdf0e10cSrcweir 	for( ;; )
791*cdf0e10cSrcweir 	{
792*cdf0e10cSrcweir 		DirectoryItem aItem2;
793*cdf0e10cSrcweir 		nRet = aDir.getNextItem( aItem2 );
794*cdf0e10cSrcweir 		if( nRet != FileBase::E_None )
795*cdf0e10cSrcweir 			break;
796*cdf0e10cSrcweir 
797*cdf0e10cSrcweir 		// Handle flags
798*cdf0e10cSrcweir         FileStatus aFileStatus2( FileStatusMask_Type | FileStatusMask_FileURL );
799*cdf0e10cSrcweir 		nRet = aItem2.getFileStatus( aFileStatus2 );
800*cdf0e10cSrcweir 		::rtl::OUString aPath = aFileStatus2.getFileURL();
801*cdf0e10cSrcweir 
802*cdf0e10cSrcweir 		// Directory?
803*cdf0e10cSrcweir 		FileStatus::Type aType2 = aFileStatus2.getFileType();
804*cdf0e10cSrcweir 		sal_Bool bFolder2 = isFolder( aType2 );
805*cdf0e10cSrcweir 		if( bFolder2 )
806*cdf0e10cSrcweir 		{
807*cdf0e10cSrcweir 			implRemoveDirRecursive( aPath );
808*cdf0e10cSrcweir 		}
809*cdf0e10cSrcweir 		else
810*cdf0e10cSrcweir 		{
811*cdf0e10cSrcweir 			File::remove( aPath );
812*cdf0e10cSrcweir 		}
813*cdf0e10cSrcweir 	}
814*cdf0e10cSrcweir 	nRet = aDir.close();
815*cdf0e10cSrcweir 
816*cdf0e10cSrcweir 	nRet = Directory::remove( aDirPath );
817*cdf0e10cSrcweir }
818*cdf0e10cSrcweir #endif
819*cdf0e10cSrcweir 
820*cdf0e10cSrcweir 
821*cdf0e10cSrcweir RTLFUNC(RmDir) // JSM
822*cdf0e10cSrcweir {
823*cdf0e10cSrcweir     (void)pBasic;
824*cdf0e10cSrcweir     (void)bWrite;
825*cdf0e10cSrcweir 
826*cdf0e10cSrcweir 	rPar.Get(0)->PutEmpty();
827*cdf0e10cSrcweir 	if (rPar.Count() == 2)
828*cdf0e10cSrcweir 	{
829*cdf0e10cSrcweir 		String aPath = rPar.Get(1)->GetString();
830*cdf0e10cSrcweir 		// <-- UCB
831*cdf0e10cSrcweir 		if( hasUno() )
832*cdf0e10cSrcweir 		{
833*cdf0e10cSrcweir 			com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess();
834*cdf0e10cSrcweir 			if( xSFI.is() )
835*cdf0e10cSrcweir 			{
836*cdf0e10cSrcweir 				try
837*cdf0e10cSrcweir 				{
838*cdf0e10cSrcweir 					if( !xSFI->isFolder( aPath ) )
839*cdf0e10cSrcweir 					{
840*cdf0e10cSrcweir 						StarBASIC::Error( SbERR_PATH_NOT_FOUND );
841*cdf0e10cSrcweir 						return;
842*cdf0e10cSrcweir 					}
843*cdf0e10cSrcweir 					SbiInstance* pInst = pINST;
844*cdf0e10cSrcweir 					bool bCompatibility = ( pInst && pInst->IsCompatibility() );
845*cdf0e10cSrcweir 					if( bCompatibility )
846*cdf0e10cSrcweir 					{
847*cdf0e10cSrcweir 						Sequence< ::rtl::OUString > aContent = xSFI->getFolderContents( aPath, true );
848*cdf0e10cSrcweir 						sal_Int32 nCount = aContent.getLength();
849*cdf0e10cSrcweir 						if( nCount > 0 )
850*cdf0e10cSrcweir 						{
851*cdf0e10cSrcweir 							StarBASIC::Error( SbERR_ACCESS_ERROR );
852*cdf0e10cSrcweir 							return;
853*cdf0e10cSrcweir 						}
854*cdf0e10cSrcweir 					}
855*cdf0e10cSrcweir 
856*cdf0e10cSrcweir 					xSFI->kill( getFullPath( aPath ) );
857*cdf0e10cSrcweir 				}
858*cdf0e10cSrcweir 				catch( Exception & )
859*cdf0e10cSrcweir 				{
860*cdf0e10cSrcweir 					StarBASIC::Error( ERRCODE_IO_GENERAL );
861*cdf0e10cSrcweir 				}
862*cdf0e10cSrcweir 			}
863*cdf0e10cSrcweir 		}
864*cdf0e10cSrcweir 		else
865*cdf0e10cSrcweir 		// --> UCB
866*cdf0e10cSrcweir 		{
867*cdf0e10cSrcweir #ifdef _OLD_FILE_IMPL
868*cdf0e10cSrcweir 			DirEntry aDirEntry(aPath);
869*cdf0e10cSrcweir 			if (aDirEntry.Kill() != FSYS_ERR_OK)
870*cdf0e10cSrcweir 				StarBASIC::Error( SbERR_PATH_NOT_FOUND );
871*cdf0e10cSrcweir #else
872*cdf0e10cSrcweir 			implRemoveDirRecursive( getFullPathUNC( aPath ) );
873*cdf0e10cSrcweir #endif
874*cdf0e10cSrcweir 		}
875*cdf0e10cSrcweir 	}
876*cdf0e10cSrcweir 	else
877*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
878*cdf0e10cSrcweir }
879*cdf0e10cSrcweir 
880*cdf0e10cSrcweir RTLFUNC(SendKeys) // JSM
881*cdf0e10cSrcweir {
882*cdf0e10cSrcweir     (void)pBasic;
883*cdf0e10cSrcweir     (void)bWrite;
884*cdf0e10cSrcweir 
885*cdf0e10cSrcweir 	rPar.Get(0)->PutEmpty();
886*cdf0e10cSrcweir 	StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
887*cdf0e10cSrcweir }
888*cdf0e10cSrcweir 
889*cdf0e10cSrcweir RTLFUNC(Exp)
890*cdf0e10cSrcweir {
891*cdf0e10cSrcweir     (void)pBasic;
892*cdf0e10cSrcweir     (void)bWrite;
893*cdf0e10cSrcweir 
894*cdf0e10cSrcweir 	if( rPar.Count() < 2 )
895*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
896*cdf0e10cSrcweir 	else
897*cdf0e10cSrcweir 	{
898*cdf0e10cSrcweir 		double aDouble = rPar.Get( 1 )->GetDouble();
899*cdf0e10cSrcweir 		aDouble = exp( aDouble );
900*cdf0e10cSrcweir         checkArithmeticOverflow( aDouble );
901*cdf0e10cSrcweir 		rPar.Get( 0 )->PutDouble( aDouble );
902*cdf0e10cSrcweir 	}
903*cdf0e10cSrcweir }
904*cdf0e10cSrcweir 
905*cdf0e10cSrcweir RTLFUNC(FileLen)
906*cdf0e10cSrcweir {
907*cdf0e10cSrcweir     (void)pBasic;
908*cdf0e10cSrcweir     (void)bWrite;
909*cdf0e10cSrcweir 
910*cdf0e10cSrcweir 	if ( rPar.Count() < 2 )
911*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
912*cdf0e10cSrcweir 	else
913*cdf0e10cSrcweir 	{
914*cdf0e10cSrcweir 		SbxVariableRef pArg = rPar.Get( 1 );
915*cdf0e10cSrcweir 		String aStr( pArg->GetString() );
916*cdf0e10cSrcweir 		sal_Int32 nLen = 0;
917*cdf0e10cSrcweir 		// <-- UCB
918*cdf0e10cSrcweir 		if( hasUno() )
919*cdf0e10cSrcweir 		{
920*cdf0e10cSrcweir 			com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess();
921*cdf0e10cSrcweir 			if( xSFI.is() )
922*cdf0e10cSrcweir 			{
923*cdf0e10cSrcweir 				try
924*cdf0e10cSrcweir 				{
925*cdf0e10cSrcweir 					nLen = xSFI->getSize( getFullPath( aStr ) );
926*cdf0e10cSrcweir 				}
927*cdf0e10cSrcweir 				catch( Exception & )
928*cdf0e10cSrcweir 				{
929*cdf0e10cSrcweir 					StarBASIC::Error( ERRCODE_IO_GENERAL );
930*cdf0e10cSrcweir 				}
931*cdf0e10cSrcweir 			}
932*cdf0e10cSrcweir 		}
933*cdf0e10cSrcweir 		else
934*cdf0e10cSrcweir 		// --> UCB
935*cdf0e10cSrcweir 		{
936*cdf0e10cSrcweir #ifdef _OLD_FILE_IMPL
937*cdf0e10cSrcweir 			FileStat aStat = DirEntry( aStr );
938*cdf0e10cSrcweir 			nLen = aStat.GetSize();
939*cdf0e10cSrcweir #else
940*cdf0e10cSrcweir 			DirectoryItem aItem;
941*cdf0e10cSrcweir 			FileBase::RC nRet = DirectoryItem::get( getFullPathUNC( aStr ), aItem );
942*cdf0e10cSrcweir 			FileStatus aFileStatus( FileStatusMask_FileSize );
943*cdf0e10cSrcweir 		    nRet = aItem.getFileStatus( aFileStatus );
944*cdf0e10cSrcweir 		    nLen = (sal_Int32)aFileStatus.getFileSize();
945*cdf0e10cSrcweir #endif
946*cdf0e10cSrcweir 		}
947*cdf0e10cSrcweir 		rPar.Get(0)->PutLong( (long)nLen );
948*cdf0e10cSrcweir 	}
949*cdf0e10cSrcweir }
950*cdf0e10cSrcweir 
951*cdf0e10cSrcweir 
952*cdf0e10cSrcweir RTLFUNC(Hex)
953*cdf0e10cSrcweir {
954*cdf0e10cSrcweir     (void)pBasic;
955*cdf0e10cSrcweir     (void)bWrite;
956*cdf0e10cSrcweir 
957*cdf0e10cSrcweir 	if ( rPar.Count() < 2 )
958*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
959*cdf0e10cSrcweir 	else
960*cdf0e10cSrcweir 	{
961*cdf0e10cSrcweir 		char aBuffer[16];
962*cdf0e10cSrcweir 		SbxVariableRef pArg = rPar.Get( 1 );
963*cdf0e10cSrcweir 		if ( pArg->IsInteger() )
964*cdf0e10cSrcweir             snprintf( aBuffer, sizeof(aBuffer), "%X", pArg->GetInteger() );
965*cdf0e10cSrcweir 		else
966*cdf0e10cSrcweir             snprintf( aBuffer, sizeof(aBuffer), "%lX", static_cast<long unsigned int>(pArg->GetLong()) );
967*cdf0e10cSrcweir 		rPar.Get(0)->PutString( String::CreateFromAscii( aBuffer ) );
968*cdf0e10cSrcweir 	}
969*cdf0e10cSrcweir }
970*cdf0e10cSrcweir 
971*cdf0e10cSrcweir // InStr( [start],string,string,[compare] )
972*cdf0e10cSrcweir 
973*cdf0e10cSrcweir RTLFUNC(InStr)
974*cdf0e10cSrcweir {
975*cdf0e10cSrcweir     (void)pBasic;
976*cdf0e10cSrcweir     (void)bWrite;
977*cdf0e10cSrcweir 
978*cdf0e10cSrcweir 	sal_uIntPtr nArgCount = rPar.Count()-1;
979*cdf0e10cSrcweir 	if ( nArgCount < 2 )
980*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
981*cdf0e10cSrcweir 	else
982*cdf0e10cSrcweir 	{
983*cdf0e10cSrcweir 		sal_uInt16 nStartPos = 1;
984*cdf0e10cSrcweir 
985*cdf0e10cSrcweir 		sal_uInt16 nFirstStringPos = 1;
986*cdf0e10cSrcweir 		if ( nArgCount >= 3 )
987*cdf0e10cSrcweir 		{
988*cdf0e10cSrcweir 			sal_Int32 lStartPos = rPar.Get(1)->GetLong();
989*cdf0e10cSrcweir 			if( lStartPos <= 0 || lStartPos > 0xffff )
990*cdf0e10cSrcweir 			{
991*cdf0e10cSrcweir 				StarBASIC::Error( SbERR_BAD_ARGUMENT );
992*cdf0e10cSrcweir 				lStartPos = 1;
993*cdf0e10cSrcweir 			}
994*cdf0e10cSrcweir 			nStartPos = (sal_uInt16)lStartPos;
995*cdf0e10cSrcweir 			nFirstStringPos++;
996*cdf0e10cSrcweir 		}
997*cdf0e10cSrcweir 
998*cdf0e10cSrcweir 		SbiInstance* pInst = pINST;
999*cdf0e10cSrcweir 		int bTextMode;
1000*cdf0e10cSrcweir 		bool bCompatibility = ( pInst && pInst->IsCompatibility() );
1001*cdf0e10cSrcweir 		if( bCompatibility )
1002*cdf0e10cSrcweir 		{
1003*cdf0e10cSrcweir 			SbiRuntime* pRT = pInst ? pInst->pRun : NULL;
1004*cdf0e10cSrcweir 			bTextMode = pRT ? pRT->GetImageFlag( SBIMG_COMPARETEXT ) : sal_False;
1005*cdf0e10cSrcweir 		}
1006*cdf0e10cSrcweir 		else
1007*cdf0e10cSrcweir 		{
1008*cdf0e10cSrcweir 			bTextMode = 1;;
1009*cdf0e10cSrcweir 		}
1010*cdf0e10cSrcweir 		if ( nArgCount == 4 )
1011*cdf0e10cSrcweir 			bTextMode = rPar.Get(4)->GetInteger();
1012*cdf0e10cSrcweir 
1013*cdf0e10cSrcweir 		sal_uInt16 nPos;
1014*cdf0e10cSrcweir 		const String& rToken = rPar.Get(nFirstStringPos+1)->GetString();
1015*cdf0e10cSrcweir 
1016*cdf0e10cSrcweir 		// #97545 Always find empty string
1017*cdf0e10cSrcweir 		if( !rToken.Len() )
1018*cdf0e10cSrcweir 		{
1019*cdf0e10cSrcweir 			nPos = nStartPos;
1020*cdf0e10cSrcweir 		}
1021*cdf0e10cSrcweir 		else
1022*cdf0e10cSrcweir 		{
1023*cdf0e10cSrcweir 			if( !bTextMode )
1024*cdf0e10cSrcweir 			{
1025*cdf0e10cSrcweir 				const String& rStr1 = rPar.Get(nFirstStringPos)->GetString();
1026*cdf0e10cSrcweir 
1027*cdf0e10cSrcweir 				nPos = rStr1.Search( rToken, nStartPos-1 );
1028*cdf0e10cSrcweir 				if ( nPos == STRING_NOTFOUND )
1029*cdf0e10cSrcweir 					nPos = 0;
1030*cdf0e10cSrcweir 				else
1031*cdf0e10cSrcweir 					nPos++;
1032*cdf0e10cSrcweir 			}
1033*cdf0e10cSrcweir 			else
1034*cdf0e10cSrcweir 			{
1035*cdf0e10cSrcweir 				String aStr1 = rPar.Get(nFirstStringPos)->GetString();
1036*cdf0e10cSrcweir 				String aToken = rToken;
1037*cdf0e10cSrcweir 
1038*cdf0e10cSrcweir 				aStr1.ToUpperAscii();
1039*cdf0e10cSrcweir 				aToken.ToUpperAscii();
1040*cdf0e10cSrcweir 
1041*cdf0e10cSrcweir 				nPos = aStr1.Search( aToken, nStartPos-1 );
1042*cdf0e10cSrcweir 				if ( nPos == STRING_NOTFOUND )
1043*cdf0e10cSrcweir 					nPos = 0;
1044*cdf0e10cSrcweir 				else
1045*cdf0e10cSrcweir 					nPos++;
1046*cdf0e10cSrcweir 			}
1047*cdf0e10cSrcweir 		}
1048*cdf0e10cSrcweir 		rPar.Get(0)->PutLong( nPos );
1049*cdf0e10cSrcweir 	}
1050*cdf0e10cSrcweir }
1051*cdf0e10cSrcweir 
1052*cdf0e10cSrcweir 
1053*cdf0e10cSrcweir // InstrRev(string1, string2[, start[, compare]])
1054*cdf0e10cSrcweir 
1055*cdf0e10cSrcweir RTLFUNC(InStrRev)
1056*cdf0e10cSrcweir {
1057*cdf0e10cSrcweir     (void)pBasic;
1058*cdf0e10cSrcweir     (void)bWrite;
1059*cdf0e10cSrcweir 
1060*cdf0e10cSrcweir 	sal_uIntPtr nArgCount = rPar.Count()-1;
1061*cdf0e10cSrcweir 	if ( nArgCount < 2 )
1062*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
1063*cdf0e10cSrcweir 	else
1064*cdf0e10cSrcweir 	{
1065*cdf0e10cSrcweir 		String aStr1 = rPar.Get(1)->GetString();
1066*cdf0e10cSrcweir 		String aToken = rPar.Get(2)->GetString();
1067*cdf0e10cSrcweir 
1068*cdf0e10cSrcweir 		sal_Int32 lStartPos = -1;
1069*cdf0e10cSrcweir 		if ( nArgCount >= 3 )
1070*cdf0e10cSrcweir 		{
1071*cdf0e10cSrcweir 			lStartPos = rPar.Get(3)->GetLong();
1072*cdf0e10cSrcweir 			if( (lStartPos <= 0 && lStartPos != -1) || lStartPos > 0xffff )
1073*cdf0e10cSrcweir 			{
1074*cdf0e10cSrcweir 				StarBASIC::Error( SbERR_BAD_ARGUMENT );
1075*cdf0e10cSrcweir 				lStartPos = -1;
1076*cdf0e10cSrcweir 			}
1077*cdf0e10cSrcweir 		}
1078*cdf0e10cSrcweir 
1079*cdf0e10cSrcweir 		SbiInstance* pInst = pINST;
1080*cdf0e10cSrcweir 		int bTextMode;
1081*cdf0e10cSrcweir 		bool bCompatibility = ( pInst && pInst->IsCompatibility() );
1082*cdf0e10cSrcweir 		if( bCompatibility )
1083*cdf0e10cSrcweir 		{
1084*cdf0e10cSrcweir 			SbiRuntime* pRT = pInst ? pInst->pRun : NULL;
1085*cdf0e10cSrcweir 			bTextMode = pRT ? pRT->GetImageFlag( SBIMG_COMPARETEXT ) : sal_False;
1086*cdf0e10cSrcweir 		}
1087*cdf0e10cSrcweir 		else
1088*cdf0e10cSrcweir 		{
1089*cdf0e10cSrcweir 			bTextMode = 1;;
1090*cdf0e10cSrcweir 		}
1091*cdf0e10cSrcweir 		if ( nArgCount == 4 )
1092*cdf0e10cSrcweir 			bTextMode = rPar.Get(4)->GetInteger();
1093*cdf0e10cSrcweir 
1094*cdf0e10cSrcweir 		sal_uInt16 nStrLen = aStr1.Len();
1095*cdf0e10cSrcweir 		sal_uInt16 nStartPos = lStartPos == -1 ? nStrLen : (sal_uInt16)lStartPos;
1096*cdf0e10cSrcweir 
1097*cdf0e10cSrcweir 		sal_uInt16 nPos = 0;
1098*cdf0e10cSrcweir 		if( nStartPos <= nStrLen )
1099*cdf0e10cSrcweir 		{
1100*cdf0e10cSrcweir 			sal_uInt16 nTokenLen = aToken.Len();
1101*cdf0e10cSrcweir 			if( !nTokenLen )
1102*cdf0e10cSrcweir 			{
1103*cdf0e10cSrcweir 				// Always find empty string
1104*cdf0e10cSrcweir 				nPos = nStartPos;
1105*cdf0e10cSrcweir 			}
1106*cdf0e10cSrcweir 			else if( nStrLen > 0 )
1107*cdf0e10cSrcweir 			{
1108*cdf0e10cSrcweir 				if( !bTextMode )
1109*cdf0e10cSrcweir 				{
1110*cdf0e10cSrcweir 					::rtl::OUString aOUStr1 ( aStr1 );
1111*cdf0e10cSrcweir 					::rtl::OUString aOUToken( aToken );
1112*cdf0e10cSrcweir 				    sal_Int32 nRet = aOUStr1.lastIndexOf( aOUToken, nStartPos );
1113*cdf0e10cSrcweir 					if( nRet == -1 )
1114*cdf0e10cSrcweir 						nPos = 0;
1115*cdf0e10cSrcweir 					else
1116*cdf0e10cSrcweir 						nPos = (sal_uInt16)nRet + 1;
1117*cdf0e10cSrcweir 				}
1118*cdf0e10cSrcweir 				else
1119*cdf0e10cSrcweir 				{
1120*cdf0e10cSrcweir 					aStr1.ToUpperAscii();
1121*cdf0e10cSrcweir 					aToken.ToUpperAscii();
1122*cdf0e10cSrcweir 
1123*cdf0e10cSrcweir 					::rtl::OUString aOUStr1 ( aStr1 );
1124*cdf0e10cSrcweir 					::rtl::OUString aOUToken( aToken );
1125*cdf0e10cSrcweir 				    sal_Int32 nRet = aOUStr1.lastIndexOf( aOUToken, nStartPos );
1126*cdf0e10cSrcweir 
1127*cdf0e10cSrcweir 					if( nRet == -1 )
1128*cdf0e10cSrcweir 						nPos = 0;
1129*cdf0e10cSrcweir 					else
1130*cdf0e10cSrcweir 						nPos = (sal_uInt16)nRet + 1;
1131*cdf0e10cSrcweir 				}
1132*cdf0e10cSrcweir 			}
1133*cdf0e10cSrcweir 		}
1134*cdf0e10cSrcweir 		rPar.Get(0)->PutLong( nPos );
1135*cdf0e10cSrcweir 	}
1136*cdf0e10cSrcweir }
1137*cdf0e10cSrcweir 
1138*cdf0e10cSrcweir 
1139*cdf0e10cSrcweir /*
1140*cdf0e10cSrcweir 	Int( 2.8 ) 	=  2.0
1141*cdf0e10cSrcweir 	Int( -2.8 ) = -3.0
1142*cdf0e10cSrcweir 	Fix( 2.8 ) 	=  2.0
1143*cdf0e10cSrcweir 	Fix( -2.8 ) = -2.0    <- !!
1144*cdf0e10cSrcweir */
1145*cdf0e10cSrcweir 
1146*cdf0e10cSrcweir RTLFUNC(Int)
1147*cdf0e10cSrcweir {
1148*cdf0e10cSrcweir     (void)pBasic;
1149*cdf0e10cSrcweir     (void)bWrite;
1150*cdf0e10cSrcweir 
1151*cdf0e10cSrcweir 	if ( rPar.Count() < 2 )
1152*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
1153*cdf0e10cSrcweir 	else
1154*cdf0e10cSrcweir 	{
1155*cdf0e10cSrcweir 		SbxVariableRef pArg = rPar.Get( 1 );
1156*cdf0e10cSrcweir 		double aDouble= pArg->GetDouble();
1157*cdf0e10cSrcweir 		/*
1158*cdf0e10cSrcweir 			floor( 2.8 ) =  2.0
1159*cdf0e10cSrcweir 			floor( -2.8 ) = -3.0
1160*cdf0e10cSrcweir 		*/
1161*cdf0e10cSrcweir 		aDouble = floor( aDouble );
1162*cdf0e10cSrcweir 		rPar.Get(0)->PutDouble( aDouble );
1163*cdf0e10cSrcweir 	}
1164*cdf0e10cSrcweir }
1165*cdf0e10cSrcweir 
1166*cdf0e10cSrcweir 
1167*cdf0e10cSrcweir 
1168*cdf0e10cSrcweir RTLFUNC(Fix)
1169*cdf0e10cSrcweir {
1170*cdf0e10cSrcweir     (void)pBasic;
1171*cdf0e10cSrcweir     (void)bWrite;
1172*cdf0e10cSrcweir 
1173*cdf0e10cSrcweir 	if ( rPar.Count() < 2 )
1174*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
1175*cdf0e10cSrcweir 	else
1176*cdf0e10cSrcweir 	{
1177*cdf0e10cSrcweir 		SbxVariableRef pArg = rPar.Get( 1 );
1178*cdf0e10cSrcweir 		double aDouble = pArg->GetDouble();
1179*cdf0e10cSrcweir 		if ( aDouble >= 0.0 )
1180*cdf0e10cSrcweir 			aDouble = floor( aDouble );
1181*cdf0e10cSrcweir 		else
1182*cdf0e10cSrcweir 			aDouble = ceil( aDouble );
1183*cdf0e10cSrcweir 		rPar.Get(0)->PutDouble( aDouble );
1184*cdf0e10cSrcweir 	}
1185*cdf0e10cSrcweir }
1186*cdf0e10cSrcweir 
1187*cdf0e10cSrcweir 
1188*cdf0e10cSrcweir RTLFUNC(LCase)
1189*cdf0e10cSrcweir {
1190*cdf0e10cSrcweir     (void)pBasic;
1191*cdf0e10cSrcweir     (void)bWrite;
1192*cdf0e10cSrcweir 
1193*cdf0e10cSrcweir 	if ( rPar.Count() < 2 )
1194*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
1195*cdf0e10cSrcweir 	else
1196*cdf0e10cSrcweir 	{
1197*cdf0e10cSrcweir 		CharClass& rCharClass = GetCharClass();
1198*cdf0e10cSrcweir 		String aStr( rPar.Get(1)->GetString() );
1199*cdf0e10cSrcweir 		rCharClass.toLower( aStr );
1200*cdf0e10cSrcweir 		rPar.Get(0)->PutString( aStr );
1201*cdf0e10cSrcweir 	}
1202*cdf0e10cSrcweir }
1203*cdf0e10cSrcweir 
1204*cdf0e10cSrcweir RTLFUNC(Left)
1205*cdf0e10cSrcweir {
1206*cdf0e10cSrcweir     (void)pBasic;
1207*cdf0e10cSrcweir     (void)bWrite;
1208*cdf0e10cSrcweir 
1209*cdf0e10cSrcweir 	if ( rPar.Count() < 3 )
1210*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
1211*cdf0e10cSrcweir 	else
1212*cdf0e10cSrcweir 	{
1213*cdf0e10cSrcweir 		String aStr( rPar.Get(1)->GetString() );
1214*cdf0e10cSrcweir 		sal_Int32 lResultLen = rPar.Get(2)->GetLong();
1215*cdf0e10cSrcweir 		if( lResultLen > 0xffff )
1216*cdf0e10cSrcweir 		{
1217*cdf0e10cSrcweir 			lResultLen = 0xffff;
1218*cdf0e10cSrcweir 		}
1219*cdf0e10cSrcweir 		else if( lResultLen < 0 )
1220*cdf0e10cSrcweir 		{
1221*cdf0e10cSrcweir 			lResultLen = 0;
1222*cdf0e10cSrcweir 			StarBASIC::Error( SbERR_BAD_ARGUMENT );
1223*cdf0e10cSrcweir 		}
1224*cdf0e10cSrcweir 		aStr.Erase( (sal_uInt16)lResultLen );
1225*cdf0e10cSrcweir 		rPar.Get(0)->PutString( aStr );
1226*cdf0e10cSrcweir 	}
1227*cdf0e10cSrcweir }
1228*cdf0e10cSrcweir 
1229*cdf0e10cSrcweir RTLFUNC(Log)
1230*cdf0e10cSrcweir {
1231*cdf0e10cSrcweir     (void)pBasic;
1232*cdf0e10cSrcweir     (void)bWrite;
1233*cdf0e10cSrcweir 
1234*cdf0e10cSrcweir 	if ( rPar.Count() < 2 )
1235*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
1236*cdf0e10cSrcweir 	else
1237*cdf0e10cSrcweir 	{
1238*cdf0e10cSrcweir 		double aArg = rPar.Get(1)->GetDouble();
1239*cdf0e10cSrcweir 		if ( aArg > 0 )
1240*cdf0e10cSrcweir         {
1241*cdf0e10cSrcweir             double d = log( aArg );
1242*cdf0e10cSrcweir             checkArithmeticOverflow( d );
1243*cdf0e10cSrcweir 			rPar.Get( 0 )->PutDouble( d );
1244*cdf0e10cSrcweir         }
1245*cdf0e10cSrcweir 		else
1246*cdf0e10cSrcweir 			StarBASIC::Error( SbERR_BAD_ARGUMENT );
1247*cdf0e10cSrcweir 	}
1248*cdf0e10cSrcweir }
1249*cdf0e10cSrcweir 
1250*cdf0e10cSrcweir RTLFUNC(LTrim)
1251*cdf0e10cSrcweir {
1252*cdf0e10cSrcweir     (void)pBasic;
1253*cdf0e10cSrcweir     (void)bWrite;
1254*cdf0e10cSrcweir 
1255*cdf0e10cSrcweir 	if ( rPar.Count() < 2 )
1256*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
1257*cdf0e10cSrcweir 	else
1258*cdf0e10cSrcweir 	{
1259*cdf0e10cSrcweir 		String aStr( rPar.Get(1)->GetString() );
1260*cdf0e10cSrcweir 		aStr.EraseLeadingChars();
1261*cdf0e10cSrcweir 		rPar.Get(0)->PutString( aStr );
1262*cdf0e10cSrcweir 	}
1263*cdf0e10cSrcweir }
1264*cdf0e10cSrcweir 
1265*cdf0e10cSrcweir 
1266*cdf0e10cSrcweir // Mid( String, nStart, nLength )
1267*cdf0e10cSrcweir 
1268*cdf0e10cSrcweir RTLFUNC(Mid)
1269*cdf0e10cSrcweir {
1270*cdf0e10cSrcweir     (void)pBasic;
1271*cdf0e10cSrcweir     (void)bWrite;
1272*cdf0e10cSrcweir 
1273*cdf0e10cSrcweir 	sal_uIntPtr nArgCount = rPar.Count()-1;
1274*cdf0e10cSrcweir 	if ( nArgCount < 2 )
1275*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
1276*cdf0e10cSrcweir 	else
1277*cdf0e10cSrcweir 	{
1278*cdf0e10cSrcweir 		// #23178: Funktionalitaet von Mid$ als Anweisung nachbilden, indem
1279*cdf0e10cSrcweir 		// als weiterer (4.) Parameter ein Ersetzungsstring aufgenommen wird.
1280*cdf0e10cSrcweir 		// Anders als im Original kann in dieser Variante der 3. Parameter
1281*cdf0e10cSrcweir 		// nLength nicht weggelassen werden. Ist ueber bWrite schon vorgesehen.
1282*cdf0e10cSrcweir 		if( nArgCount == 4 )
1283*cdf0e10cSrcweir 			bWrite = sal_True;
1284*cdf0e10cSrcweir 
1285*cdf0e10cSrcweir 		String aArgStr = rPar.Get(1)->GetString();
1286*cdf0e10cSrcweir 		sal_uInt16 nStartPos = (sal_uInt16)(rPar.Get(2)->GetLong() );
1287*cdf0e10cSrcweir 		if ( nStartPos == 0 )
1288*cdf0e10cSrcweir 			StarBASIC::Error( SbERR_BAD_ARGUMENT );
1289*cdf0e10cSrcweir 		else
1290*cdf0e10cSrcweir 		{
1291*cdf0e10cSrcweir 			nStartPos--;
1292*cdf0e10cSrcweir 			sal_uInt16 nLen = 0xffff;
1293*cdf0e10cSrcweir 			bool bWriteNoLenParam = false;
1294*cdf0e10cSrcweir 			if ( nArgCount == 3 || bWrite )
1295*cdf0e10cSrcweir 			{
1296*cdf0e10cSrcweir 				sal_Int32 n = rPar.Get(3)->GetLong();
1297*cdf0e10cSrcweir 				if( bWrite && n == -1 )
1298*cdf0e10cSrcweir 					bWriteNoLenParam = true;
1299*cdf0e10cSrcweir 				nLen = (sal_uInt16)n;
1300*cdf0e10cSrcweir 			}
1301*cdf0e10cSrcweir 			String aResultStr;
1302*cdf0e10cSrcweir 			if ( bWrite )
1303*cdf0e10cSrcweir 			{
1304*cdf0e10cSrcweir 				SbiInstance* pInst = pINST;
1305*cdf0e10cSrcweir 				bool bCompatibility = ( pInst && pInst->IsCompatibility() );
1306*cdf0e10cSrcweir 				if( bCompatibility )
1307*cdf0e10cSrcweir 				{
1308*cdf0e10cSrcweir 					sal_uInt16 nArgLen = aArgStr.Len();
1309*cdf0e10cSrcweir 					if( nStartPos + 1 > nArgLen )
1310*cdf0e10cSrcweir 					{
1311*cdf0e10cSrcweir 						StarBASIC::Error( SbERR_BAD_ARGUMENT );
1312*cdf0e10cSrcweir 						return;
1313*cdf0e10cSrcweir 					}
1314*cdf0e10cSrcweir 
1315*cdf0e10cSrcweir 					String aReplaceStr = rPar.Get(4)->GetString();
1316*cdf0e10cSrcweir 					sal_uInt16 nReplaceStrLen = aReplaceStr.Len();
1317*cdf0e10cSrcweir 					sal_uInt16 nReplaceLen;
1318*cdf0e10cSrcweir 					if( bWriteNoLenParam )
1319*cdf0e10cSrcweir 					{
1320*cdf0e10cSrcweir 						nReplaceLen = nReplaceStrLen;
1321*cdf0e10cSrcweir 					}
1322*cdf0e10cSrcweir 					else
1323*cdf0e10cSrcweir 					{
1324*cdf0e10cSrcweir 						nReplaceLen = nLen;
1325*cdf0e10cSrcweir 						if( nReplaceLen > nReplaceStrLen )
1326*cdf0e10cSrcweir 							nReplaceLen = nReplaceStrLen;
1327*cdf0e10cSrcweir 					}
1328*cdf0e10cSrcweir 
1329*cdf0e10cSrcweir 					sal_uInt16 nReplaceEndPos = nStartPos + nReplaceLen;
1330*cdf0e10cSrcweir 					if( nReplaceEndPos > nArgLen )
1331*cdf0e10cSrcweir 						nReplaceLen -= (nReplaceEndPos - nArgLen);
1332*cdf0e10cSrcweir 
1333*cdf0e10cSrcweir 					aResultStr = aArgStr;
1334*cdf0e10cSrcweir 					sal_uInt16 nErase = nReplaceLen;
1335*cdf0e10cSrcweir 					aResultStr.Erase( nStartPos, nErase );
1336*cdf0e10cSrcweir 					aResultStr.Insert( aReplaceStr, 0, nReplaceLen, nStartPos );
1337*cdf0e10cSrcweir 				}
1338*cdf0e10cSrcweir 				else
1339*cdf0e10cSrcweir 				{
1340*cdf0e10cSrcweir 					aResultStr = aArgStr;
1341*cdf0e10cSrcweir 					aResultStr.Erase( nStartPos, nLen );
1342*cdf0e10cSrcweir 					aResultStr.Insert(rPar.Get(4)->GetString(),0,nLen,nStartPos);
1343*cdf0e10cSrcweir 				}
1344*cdf0e10cSrcweir 
1345*cdf0e10cSrcweir 				rPar.Get(1)->PutString( aResultStr );
1346*cdf0e10cSrcweir 			}
1347*cdf0e10cSrcweir 			else
1348*cdf0e10cSrcweir 			{
1349*cdf0e10cSrcweir 				aResultStr = aArgStr.Copy( nStartPos, nLen );
1350*cdf0e10cSrcweir 				rPar.Get(0)->PutString( aResultStr );
1351*cdf0e10cSrcweir 			}
1352*cdf0e10cSrcweir 		}
1353*cdf0e10cSrcweir 	}
1354*cdf0e10cSrcweir }
1355*cdf0e10cSrcweir 
1356*cdf0e10cSrcweir RTLFUNC(Oct)
1357*cdf0e10cSrcweir {
1358*cdf0e10cSrcweir     (void)pBasic;
1359*cdf0e10cSrcweir     (void)bWrite;
1360*cdf0e10cSrcweir 
1361*cdf0e10cSrcweir 	if ( rPar.Count() < 2 )
1362*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
1363*cdf0e10cSrcweir 	else
1364*cdf0e10cSrcweir 	{
1365*cdf0e10cSrcweir 		char aBuffer[16];
1366*cdf0e10cSrcweir 		SbxVariableRef pArg = rPar.Get( 1 );
1367*cdf0e10cSrcweir 		if ( pArg->IsInteger() )
1368*cdf0e10cSrcweir             snprintf( aBuffer, sizeof(aBuffer), "%o", pArg->GetInteger() );
1369*cdf0e10cSrcweir 		else
1370*cdf0e10cSrcweir             snprintf( aBuffer, sizeof(aBuffer), "%lo", static_cast<long unsigned int>(pArg->GetLong()) );
1371*cdf0e10cSrcweir 		rPar.Get(0)->PutString( String::CreateFromAscii( aBuffer ) );
1372*cdf0e10cSrcweir 	}
1373*cdf0e10cSrcweir }
1374*cdf0e10cSrcweir 
1375*cdf0e10cSrcweir // Replace(expression, find, replace[, start[, count[, compare]]])
1376*cdf0e10cSrcweir 
1377*cdf0e10cSrcweir RTLFUNC(Replace)
1378*cdf0e10cSrcweir {
1379*cdf0e10cSrcweir     (void)pBasic;
1380*cdf0e10cSrcweir     (void)bWrite;
1381*cdf0e10cSrcweir 
1382*cdf0e10cSrcweir 	sal_uIntPtr nArgCount = rPar.Count()-1;
1383*cdf0e10cSrcweir 	if ( nArgCount < 3 || nArgCount > 6 )
1384*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
1385*cdf0e10cSrcweir 	else
1386*cdf0e10cSrcweir 	{
1387*cdf0e10cSrcweir 		String aExpStr = rPar.Get(1)->GetString();
1388*cdf0e10cSrcweir 		String aFindStr = rPar.Get(2)->GetString();
1389*cdf0e10cSrcweir 		String aReplaceStr = rPar.Get(3)->GetString();
1390*cdf0e10cSrcweir 
1391*cdf0e10cSrcweir 		sal_Int32 lStartPos = 1;
1392*cdf0e10cSrcweir 		if ( nArgCount >= 4 )
1393*cdf0e10cSrcweir 		{
1394*cdf0e10cSrcweir 			if( rPar.Get(4)->GetType() != SbxEMPTY )
1395*cdf0e10cSrcweir 				lStartPos = rPar.Get(4)->GetLong();
1396*cdf0e10cSrcweir 			if( lStartPos < 1  || lStartPos > 0xffff )
1397*cdf0e10cSrcweir 			{
1398*cdf0e10cSrcweir 				StarBASIC::Error( SbERR_BAD_ARGUMENT );
1399*cdf0e10cSrcweir 				lStartPos = 1;
1400*cdf0e10cSrcweir 			}
1401*cdf0e10cSrcweir 		}
1402*cdf0e10cSrcweir 
1403*cdf0e10cSrcweir 		sal_Int32 lCount = -1;
1404*cdf0e10cSrcweir 		if( nArgCount >=5 )
1405*cdf0e10cSrcweir 		{
1406*cdf0e10cSrcweir 			if( rPar.Get(5)->GetType() != SbxEMPTY )
1407*cdf0e10cSrcweir 				lCount = rPar.Get(5)->GetLong();
1408*cdf0e10cSrcweir 			if( lCount < -1 || lCount > 0xffff )
1409*cdf0e10cSrcweir 			{
1410*cdf0e10cSrcweir 				StarBASIC::Error( SbERR_BAD_ARGUMENT );
1411*cdf0e10cSrcweir 				lCount = -1;
1412*cdf0e10cSrcweir 			}
1413*cdf0e10cSrcweir 		}
1414*cdf0e10cSrcweir 
1415*cdf0e10cSrcweir 		SbiInstance* pInst = pINST;
1416*cdf0e10cSrcweir 		int bTextMode;
1417*cdf0e10cSrcweir 		bool bCompatibility = ( pInst && pInst->IsCompatibility() );
1418*cdf0e10cSrcweir 		if( bCompatibility )
1419*cdf0e10cSrcweir 		{
1420*cdf0e10cSrcweir 			SbiRuntime* pRT = pInst ? pInst->pRun : NULL;
1421*cdf0e10cSrcweir 			bTextMode = pRT ? pRT->GetImageFlag( SBIMG_COMPARETEXT ) : sal_False;
1422*cdf0e10cSrcweir 		}
1423*cdf0e10cSrcweir 		else
1424*cdf0e10cSrcweir 		{
1425*cdf0e10cSrcweir 			bTextMode = 1;
1426*cdf0e10cSrcweir 		}
1427*cdf0e10cSrcweir 		if ( nArgCount == 6 )
1428*cdf0e10cSrcweir 			bTextMode = rPar.Get(6)->GetInteger();
1429*cdf0e10cSrcweir 
1430*cdf0e10cSrcweir 		sal_uInt16 nExpStrLen = aExpStr.Len();
1431*cdf0e10cSrcweir 		sal_uInt16 nFindStrLen = aFindStr.Len();
1432*cdf0e10cSrcweir 		sal_uInt16 nReplaceStrLen = aReplaceStr.Len();
1433*cdf0e10cSrcweir 
1434*cdf0e10cSrcweir 		if( lStartPos <= nExpStrLen )
1435*cdf0e10cSrcweir 		{
1436*cdf0e10cSrcweir 			sal_uInt16 nPos = static_cast<sal_uInt16>( lStartPos - 1 );
1437*cdf0e10cSrcweir 			sal_uInt16 nCounts = 0;
1438*cdf0e10cSrcweir 			while( lCount == -1 || lCount > nCounts )
1439*cdf0e10cSrcweir 			{
1440*cdf0e10cSrcweir 				String aSrcStr( aExpStr );
1441*cdf0e10cSrcweir 				if( bTextMode )
1442*cdf0e10cSrcweir 				{
1443*cdf0e10cSrcweir 					aSrcStr.ToUpperAscii();
1444*cdf0e10cSrcweir 					aFindStr.ToUpperAscii();
1445*cdf0e10cSrcweir 				}
1446*cdf0e10cSrcweir 				nPos = aSrcStr.Search( aFindStr, nPos );
1447*cdf0e10cSrcweir 				if( nPos != STRING_NOTFOUND )
1448*cdf0e10cSrcweir 				{
1449*cdf0e10cSrcweir 					aExpStr.Replace( nPos, nFindStrLen, aReplaceStr );
1450*cdf0e10cSrcweir 					nPos = nPos - nFindStrLen + nReplaceStrLen + 1;
1451*cdf0e10cSrcweir 					nCounts++;
1452*cdf0e10cSrcweir 				}
1453*cdf0e10cSrcweir 				else
1454*cdf0e10cSrcweir 				{
1455*cdf0e10cSrcweir 					break;
1456*cdf0e10cSrcweir 				}
1457*cdf0e10cSrcweir 			}
1458*cdf0e10cSrcweir 		}
1459*cdf0e10cSrcweir 		rPar.Get(0)->PutString( aExpStr.Copy( static_cast<sal_uInt16>(lStartPos - 1) )  );
1460*cdf0e10cSrcweir 	}
1461*cdf0e10cSrcweir }
1462*cdf0e10cSrcweir 
1463*cdf0e10cSrcweir RTLFUNC(Right)
1464*cdf0e10cSrcweir {
1465*cdf0e10cSrcweir     (void)pBasic;
1466*cdf0e10cSrcweir     (void)bWrite;
1467*cdf0e10cSrcweir 
1468*cdf0e10cSrcweir 	if ( rPar.Count() < 3 )
1469*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
1470*cdf0e10cSrcweir 	else
1471*cdf0e10cSrcweir 	{
1472*cdf0e10cSrcweir 		const String& rStr = rPar.Get(1)->GetString();
1473*cdf0e10cSrcweir 		sal_Int32 lResultLen = rPar.Get(2)->GetLong();
1474*cdf0e10cSrcweir 		if( lResultLen > 0xffff )
1475*cdf0e10cSrcweir 		{
1476*cdf0e10cSrcweir 			lResultLen = 0xffff;
1477*cdf0e10cSrcweir 		}
1478*cdf0e10cSrcweir 		else if( lResultLen < 0 )
1479*cdf0e10cSrcweir 		{
1480*cdf0e10cSrcweir 			lResultLen = 0;
1481*cdf0e10cSrcweir 			StarBASIC::Error( SbERR_BAD_ARGUMENT );
1482*cdf0e10cSrcweir 		}
1483*cdf0e10cSrcweir 		sal_uInt16 nResultLen = (sal_uInt16)lResultLen;
1484*cdf0e10cSrcweir 		sal_uInt16 nStrLen = rStr.Len();
1485*cdf0e10cSrcweir 		if ( nResultLen > nStrLen )
1486*cdf0e10cSrcweir 			nResultLen = nStrLen;
1487*cdf0e10cSrcweir 		String aResultStr = rStr.Copy( nStrLen-nResultLen );
1488*cdf0e10cSrcweir 		rPar.Get(0)->PutString( aResultStr );
1489*cdf0e10cSrcweir 	}
1490*cdf0e10cSrcweir }
1491*cdf0e10cSrcweir 
1492*cdf0e10cSrcweir RTLFUNC(RTL)
1493*cdf0e10cSrcweir {
1494*cdf0e10cSrcweir     (void)pBasic;
1495*cdf0e10cSrcweir     (void)bWrite;
1496*cdf0e10cSrcweir 
1497*cdf0e10cSrcweir 	rPar.Get( 0 )->PutObject( pBasic->getRTL() );
1498*cdf0e10cSrcweir }
1499*cdf0e10cSrcweir 
1500*cdf0e10cSrcweir RTLFUNC(RTrim)
1501*cdf0e10cSrcweir {
1502*cdf0e10cSrcweir     (void)pBasic;
1503*cdf0e10cSrcweir     (void)bWrite;
1504*cdf0e10cSrcweir 
1505*cdf0e10cSrcweir 	if ( rPar.Count() < 2 )
1506*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
1507*cdf0e10cSrcweir 	else
1508*cdf0e10cSrcweir 	{
1509*cdf0e10cSrcweir 		String aStr( rPar.Get(1)->GetString() );
1510*cdf0e10cSrcweir 		aStr.EraseTrailingChars();
1511*cdf0e10cSrcweir 		rPar.Get(0)->PutString( aStr );
1512*cdf0e10cSrcweir 	}
1513*cdf0e10cSrcweir }
1514*cdf0e10cSrcweir 
1515*cdf0e10cSrcweir RTLFUNC(Sgn)
1516*cdf0e10cSrcweir {
1517*cdf0e10cSrcweir     (void)pBasic;
1518*cdf0e10cSrcweir     (void)bWrite;
1519*cdf0e10cSrcweir 
1520*cdf0e10cSrcweir 	if ( rPar.Count() < 2 )
1521*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
1522*cdf0e10cSrcweir 	else
1523*cdf0e10cSrcweir 	{
1524*cdf0e10cSrcweir 		double aDouble = rPar.Get(1)->GetDouble();
1525*cdf0e10cSrcweir 		sal_Int16 nResult = 0;
1526*cdf0e10cSrcweir 		if ( aDouble > 0 )
1527*cdf0e10cSrcweir 			nResult = 1;
1528*cdf0e10cSrcweir 		else if ( aDouble < 0 )
1529*cdf0e10cSrcweir 			nResult = -1;
1530*cdf0e10cSrcweir 		rPar.Get(0)->PutInteger( nResult );
1531*cdf0e10cSrcweir 	}
1532*cdf0e10cSrcweir }
1533*cdf0e10cSrcweir 
1534*cdf0e10cSrcweir RTLFUNC(Space)
1535*cdf0e10cSrcweir {
1536*cdf0e10cSrcweir     (void)pBasic;
1537*cdf0e10cSrcweir     (void)bWrite;
1538*cdf0e10cSrcweir 
1539*cdf0e10cSrcweir 	if ( rPar.Count() < 2 )
1540*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
1541*cdf0e10cSrcweir 	else
1542*cdf0e10cSrcweir 	{
1543*cdf0e10cSrcweir 		String aStr;
1544*cdf0e10cSrcweir 		aStr.Fill( (sal_uInt16)(rPar.Get(1)->GetLong() ));
1545*cdf0e10cSrcweir 		rPar.Get(0)->PutString( aStr );
1546*cdf0e10cSrcweir 	}
1547*cdf0e10cSrcweir }
1548*cdf0e10cSrcweir 
1549*cdf0e10cSrcweir RTLFUNC(Spc)
1550*cdf0e10cSrcweir {
1551*cdf0e10cSrcweir     (void)pBasic;
1552*cdf0e10cSrcweir     (void)bWrite;
1553*cdf0e10cSrcweir 
1554*cdf0e10cSrcweir 	if ( rPar.Count() < 2 )
1555*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
1556*cdf0e10cSrcweir 	else
1557*cdf0e10cSrcweir 	{
1558*cdf0e10cSrcweir 		String aStr;
1559*cdf0e10cSrcweir 		aStr.Fill( (sal_uInt16)(rPar.Get(1)->GetLong() ));
1560*cdf0e10cSrcweir 		rPar.Get(0)->PutString( aStr );
1561*cdf0e10cSrcweir 	}
1562*cdf0e10cSrcweir }
1563*cdf0e10cSrcweir 
1564*cdf0e10cSrcweir RTLFUNC(Sqr)
1565*cdf0e10cSrcweir {
1566*cdf0e10cSrcweir     (void)pBasic;
1567*cdf0e10cSrcweir     (void)bWrite;
1568*cdf0e10cSrcweir 
1569*cdf0e10cSrcweir 	if ( rPar.Count() < 2 )
1570*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
1571*cdf0e10cSrcweir 	else
1572*cdf0e10cSrcweir 	{
1573*cdf0e10cSrcweir 		double aDouble = rPar.Get(1)->GetDouble();
1574*cdf0e10cSrcweir 		if ( aDouble >= 0 )
1575*cdf0e10cSrcweir 			rPar.Get(0)->PutDouble( sqrt( aDouble ));
1576*cdf0e10cSrcweir 		else
1577*cdf0e10cSrcweir 			StarBASIC::Error( SbERR_BAD_ARGUMENT );
1578*cdf0e10cSrcweir 	}
1579*cdf0e10cSrcweir }
1580*cdf0e10cSrcweir 
1581*cdf0e10cSrcweir RTLFUNC(Str)
1582*cdf0e10cSrcweir {
1583*cdf0e10cSrcweir     (void)pBasic;
1584*cdf0e10cSrcweir     (void)bWrite;
1585*cdf0e10cSrcweir 
1586*cdf0e10cSrcweir 	if ( rPar.Count() < 2 )
1587*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
1588*cdf0e10cSrcweir 	else
1589*cdf0e10cSrcweir 	{
1590*cdf0e10cSrcweir 		String aStr;
1591*cdf0e10cSrcweir 		SbxVariableRef pArg = rPar.Get( 1 );
1592*cdf0e10cSrcweir 		pArg->Format( aStr );
1593*cdf0e10cSrcweir 
1594*cdf0e10cSrcweir 		// Numbers start with a space
1595*cdf0e10cSrcweir 		if( pArg->IsNumericRTL() )
1596*cdf0e10cSrcweir         {
1597*cdf0e10cSrcweir     		// Kommas durch Punkte ersetzen, damit es symmetrisch zu Val ist!
1598*cdf0e10cSrcweir 	    	aStr.SearchAndReplace( ',', '.' );
1599*cdf0e10cSrcweir 
1600*cdf0e10cSrcweir 			SbiInstance* pInst = pINST;
1601*cdf0e10cSrcweir 			bool bCompatibility = ( pInst && pInst->IsCompatibility() );
1602*cdf0e10cSrcweir 			if( bCompatibility )
1603*cdf0e10cSrcweir 			{
1604*cdf0e10cSrcweir 				xub_StrLen nLen = aStr.Len();
1605*cdf0e10cSrcweir 
1606*cdf0e10cSrcweir 				const sal_Unicode* pBuf = aStr.GetBuffer();
1607*cdf0e10cSrcweir 
1608*cdf0e10cSrcweir 				bool bNeg = ( pBuf[0] == '-' );
1609*cdf0e10cSrcweir 				sal_uInt16 iZeroSearch = 0;
1610*cdf0e10cSrcweir 				if( bNeg )
1611*cdf0e10cSrcweir 					iZeroSearch++;
1612*cdf0e10cSrcweir 
1613*cdf0e10cSrcweir 				sal_uInt16 iNext = iZeroSearch + 1;
1614*cdf0e10cSrcweir 				if( pBuf[iZeroSearch] == '0' && nLen > iNext && pBuf[iNext] == '.' )
1615*cdf0e10cSrcweir 				{
1616*cdf0e10cSrcweir 					aStr.Erase( iZeroSearch, 1 );
1617*cdf0e10cSrcweir 					pBuf = aStr.GetBuffer();
1618*cdf0e10cSrcweir 				}
1619*cdf0e10cSrcweir 				if( !bNeg )
1620*cdf0e10cSrcweir 					aStr.Insert( ' ', 0 );
1621*cdf0e10cSrcweir 			}
1622*cdf0e10cSrcweir 			else
1623*cdf0e10cSrcweir 				aStr.Insert( ' ', 0 );
1624*cdf0e10cSrcweir         }
1625*cdf0e10cSrcweir 		rPar.Get(0)->PutString( aStr );
1626*cdf0e10cSrcweir 	}
1627*cdf0e10cSrcweir }
1628*cdf0e10cSrcweir 
1629*cdf0e10cSrcweir RTLFUNC(StrComp)
1630*cdf0e10cSrcweir {
1631*cdf0e10cSrcweir     (void)pBasic;
1632*cdf0e10cSrcweir     (void)bWrite;
1633*cdf0e10cSrcweir 
1634*cdf0e10cSrcweir 	if ( rPar.Count() < 3 )
1635*cdf0e10cSrcweir 	{
1636*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
1637*cdf0e10cSrcweir 		rPar.Get(0)->PutEmpty();
1638*cdf0e10cSrcweir 		return;
1639*cdf0e10cSrcweir 	}
1640*cdf0e10cSrcweir 	const String& rStr1 = rPar.Get(1)->GetString();
1641*cdf0e10cSrcweir 	const String& rStr2 = rPar.Get(2)->GetString();
1642*cdf0e10cSrcweir 
1643*cdf0e10cSrcweir 	SbiInstance* pInst = pINST;
1644*cdf0e10cSrcweir 	sal_Int16 nTextCompare;
1645*cdf0e10cSrcweir 	bool bCompatibility = ( pInst && pInst->IsCompatibility() );
1646*cdf0e10cSrcweir 	if( bCompatibility )
1647*cdf0e10cSrcweir 	{
1648*cdf0e10cSrcweir 		SbiRuntime* pRT = pInst ? pInst->pRun : NULL;
1649*cdf0e10cSrcweir 		nTextCompare = pRT ? pRT->GetImageFlag( SBIMG_COMPARETEXT ) : sal_False;
1650*cdf0e10cSrcweir 	}
1651*cdf0e10cSrcweir 	else
1652*cdf0e10cSrcweir 	{
1653*cdf0e10cSrcweir 		nTextCompare = sal_True;
1654*cdf0e10cSrcweir 	}
1655*cdf0e10cSrcweir 	if ( rPar.Count() == 4 )
1656*cdf0e10cSrcweir 		nTextCompare = rPar.Get(3)->GetInteger();
1657*cdf0e10cSrcweir 
1658*cdf0e10cSrcweir 	if( !bCompatibility )
1659*cdf0e10cSrcweir 		nTextCompare = !nTextCompare;
1660*cdf0e10cSrcweir 
1661*cdf0e10cSrcweir 	StringCompare aResult;
1662*cdf0e10cSrcweir     sal_Int32 nRetValue = 0;
1663*cdf0e10cSrcweir 	if( nTextCompare )
1664*cdf0e10cSrcweir     {
1665*cdf0e10cSrcweir         ::utl::TransliterationWrapper* pTransliterationWrapper = GetSbData()->pTransliterationWrapper;
1666*cdf0e10cSrcweir         if( !pTransliterationWrapper )
1667*cdf0e10cSrcweir         {
1668*cdf0e10cSrcweir 		    com::sun::star::uno::Reference< XMultiServiceFactory > xSMgr = getProcessServiceFactory();
1669*cdf0e10cSrcweir             pTransliterationWrapper = GetSbData()->pTransliterationWrapper =
1670*cdf0e10cSrcweir     	        new ::utl::TransliterationWrapper( xSMgr,
1671*cdf0e10cSrcweir                     ::com::sun::star::i18n::TransliterationModules_IGNORE_CASE |
1672*cdf0e10cSrcweir                     ::com::sun::star::i18n::TransliterationModules_IGNORE_KANA |
1673*cdf0e10cSrcweir                     ::com::sun::star::i18n::TransliterationModules_IGNORE_WIDTH );
1674*cdf0e10cSrcweir         }
1675*cdf0e10cSrcweir 
1676*cdf0e10cSrcweir         LanguageType eLangType = GetpApp()->GetSettings().GetLanguage();
1677*cdf0e10cSrcweir         pTransliterationWrapper->loadModuleIfNeeded( eLangType );
1678*cdf0e10cSrcweir         nRetValue = pTransliterationWrapper->compareString( rStr1, rStr2 );
1679*cdf0e10cSrcweir     }
1680*cdf0e10cSrcweir 	else
1681*cdf0e10cSrcweir     {
1682*cdf0e10cSrcweir 		aResult = rStr1.CompareTo( rStr2 );
1683*cdf0e10cSrcweir 	    if ( aResult == COMPARE_LESS )
1684*cdf0e10cSrcweir 		    nRetValue = -1;
1685*cdf0e10cSrcweir 	    else if ( aResult == COMPARE_GREATER )
1686*cdf0e10cSrcweir 		    nRetValue = 1;
1687*cdf0e10cSrcweir     }
1688*cdf0e10cSrcweir 
1689*cdf0e10cSrcweir 	rPar.Get(0)->PutInteger( sal::static_int_cast< sal_Int16 >( nRetValue ) );
1690*cdf0e10cSrcweir }
1691*cdf0e10cSrcweir 
1692*cdf0e10cSrcweir RTLFUNC(String)
1693*cdf0e10cSrcweir {
1694*cdf0e10cSrcweir     (void)pBasic;
1695*cdf0e10cSrcweir     (void)bWrite;
1696*cdf0e10cSrcweir 
1697*cdf0e10cSrcweir 	if ( rPar.Count() < 2 )
1698*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
1699*cdf0e10cSrcweir 	else
1700*cdf0e10cSrcweir 	{
1701*cdf0e10cSrcweir 		String aStr;
1702*cdf0e10cSrcweir 		sal_Unicode aFiller;
1703*cdf0e10cSrcweir 		sal_Int32 lCount = rPar.Get(1)->GetLong();
1704*cdf0e10cSrcweir 		if( lCount < 0 || lCount > 0xffff )
1705*cdf0e10cSrcweir 			StarBASIC::Error( SbERR_BAD_ARGUMENT );
1706*cdf0e10cSrcweir 		sal_uInt16 nCount = (sal_uInt16)lCount;
1707*cdf0e10cSrcweir 		if( rPar.Get(2)->GetType() == SbxINTEGER )
1708*cdf0e10cSrcweir 			aFiller = (sal_Unicode)rPar.Get(2)->GetInteger();
1709*cdf0e10cSrcweir 		else
1710*cdf0e10cSrcweir 		{
1711*cdf0e10cSrcweir 			const String& rStr = rPar.Get(2)->GetString();
1712*cdf0e10cSrcweir 			aFiller = rStr.GetBuffer()[0];
1713*cdf0e10cSrcweir 		}
1714*cdf0e10cSrcweir 		aStr.Fill( nCount, aFiller );
1715*cdf0e10cSrcweir 		rPar.Get(0)->PutString( aStr );
1716*cdf0e10cSrcweir 	}
1717*cdf0e10cSrcweir }
1718*cdf0e10cSrcweir 
1719*cdf0e10cSrcweir RTLFUNC(Tan)
1720*cdf0e10cSrcweir {
1721*cdf0e10cSrcweir     (void)pBasic;
1722*cdf0e10cSrcweir     (void)bWrite;
1723*cdf0e10cSrcweir 
1724*cdf0e10cSrcweir 	if ( rPar.Count() < 2 )
1725*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
1726*cdf0e10cSrcweir 	else
1727*cdf0e10cSrcweir 	{
1728*cdf0e10cSrcweir 		SbxVariableRef pArg = rPar.Get( 1 );
1729*cdf0e10cSrcweir 		rPar.Get( 0 )->PutDouble( tan( pArg->GetDouble() ) );
1730*cdf0e10cSrcweir 	}
1731*cdf0e10cSrcweir }
1732*cdf0e10cSrcweir 
1733*cdf0e10cSrcweir RTLFUNC(UCase)
1734*cdf0e10cSrcweir {
1735*cdf0e10cSrcweir     (void)pBasic;
1736*cdf0e10cSrcweir     (void)bWrite;
1737*cdf0e10cSrcweir 
1738*cdf0e10cSrcweir 	if ( rPar.Count() < 2 )
1739*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
1740*cdf0e10cSrcweir 	else
1741*cdf0e10cSrcweir 	{
1742*cdf0e10cSrcweir 		CharClass& rCharClass = GetCharClass();
1743*cdf0e10cSrcweir 		String aStr( rPar.Get(1)->GetString() );
1744*cdf0e10cSrcweir 		rCharClass.toUpper( aStr );
1745*cdf0e10cSrcweir 		rPar.Get(0)->PutString( aStr );
1746*cdf0e10cSrcweir 	}
1747*cdf0e10cSrcweir }
1748*cdf0e10cSrcweir 
1749*cdf0e10cSrcweir 
1750*cdf0e10cSrcweir RTLFUNC(Val)
1751*cdf0e10cSrcweir {
1752*cdf0e10cSrcweir     (void)pBasic;
1753*cdf0e10cSrcweir     (void)bWrite;
1754*cdf0e10cSrcweir 
1755*cdf0e10cSrcweir 	if ( rPar.Count() < 2 )
1756*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
1757*cdf0e10cSrcweir 	else
1758*cdf0e10cSrcweir 	{
1759*cdf0e10cSrcweir 		double nResult = 0.0;
1760*cdf0e10cSrcweir 		char* pEndPtr;
1761*cdf0e10cSrcweir 
1762*cdf0e10cSrcweir 		String aStr( rPar.Get(1)->GetString() );
1763*cdf0e10cSrcweir // lt. Mikkysoft bei Kommas abbrechen!
1764*cdf0e10cSrcweir //		for( sal_uInt16 n=0; n < aStr.Len(); n++ )
1765*cdf0e10cSrcweir //			if( aStr[n] == ',' ) aStr[n] = '.';
1766*cdf0e10cSrcweir 
1767*cdf0e10cSrcweir 		FilterWhiteSpace( aStr );
1768*cdf0e10cSrcweir 		if ( aStr.GetBuffer()[0] == '&' && aStr.Len() > 1 )
1769*cdf0e10cSrcweir 		{
1770*cdf0e10cSrcweir 			int nRadix = 10;
1771*cdf0e10cSrcweir 			char aChar = (char)aStr.GetBuffer()[1];
1772*cdf0e10cSrcweir 			if ( aChar == 'h' || aChar == 'H' )
1773*cdf0e10cSrcweir 				nRadix = 16;
1774*cdf0e10cSrcweir 			else if ( aChar == 'o' || aChar == 'O' )
1775*cdf0e10cSrcweir 				nRadix = 8;
1776*cdf0e10cSrcweir 			if ( nRadix != 10 )
1777*cdf0e10cSrcweir 			{
1778*cdf0e10cSrcweir 				ByteString aByteStr( aStr, gsl_getSystemTextEncoding() );
1779*cdf0e10cSrcweir 				sal_Int16 nlResult = (sal_Int16)strtol( aByteStr.GetBuffer()+2, &pEndPtr, nRadix);
1780*cdf0e10cSrcweir 				nResult = (double)nlResult;
1781*cdf0e10cSrcweir 			}
1782*cdf0e10cSrcweir 		}
1783*cdf0e10cSrcweir 		else
1784*cdf0e10cSrcweir 		{
1785*cdf0e10cSrcweir 			// #57844 Lokalisierte Funktion benutzen
1786*cdf0e10cSrcweir 			nResult = ::rtl::math::stringToDouble( aStr, '.', ',', NULL, NULL );
1787*cdf0e10cSrcweir             checkArithmeticOverflow( nResult );
1788*cdf0e10cSrcweir 			// ATL: nResult = strtod( aStr.GetStr(), &pEndPtr );
1789*cdf0e10cSrcweir 		}
1790*cdf0e10cSrcweir 
1791*cdf0e10cSrcweir 		rPar.Get(0)->PutDouble( nResult );
1792*cdf0e10cSrcweir 	}
1793*cdf0e10cSrcweir }
1794*cdf0e10cSrcweir 
1795*cdf0e10cSrcweir 
1796*cdf0e10cSrcweir // Helper functions for date conversion
1797*cdf0e10cSrcweir sal_Int16 implGetDateDay( double aDate )
1798*cdf0e10cSrcweir {
1799*cdf0e10cSrcweir 	aDate -= 2.0; // normieren: 1.1.1900 => 0.0
1800*cdf0e10cSrcweir 	Date aRefDate( 1, 1, 1900 );
1801*cdf0e10cSrcweir 	if ( aDate >= 0.0 )
1802*cdf0e10cSrcweir 	{
1803*cdf0e10cSrcweir 		aDate = floor( aDate );
1804*cdf0e10cSrcweir 		aRefDate += (sal_uIntPtr)aDate;
1805*cdf0e10cSrcweir 	}
1806*cdf0e10cSrcweir 	else
1807*cdf0e10cSrcweir 	{
1808*cdf0e10cSrcweir 		aDate = ceil( aDate );
1809*cdf0e10cSrcweir 		aRefDate -= (sal_uIntPtr)(-1.0 * aDate);
1810*cdf0e10cSrcweir 	}
1811*cdf0e10cSrcweir 
1812*cdf0e10cSrcweir     sal_Int16 nRet = (sal_Int16)( aRefDate.GetDay() );
1813*cdf0e10cSrcweir     return nRet;
1814*cdf0e10cSrcweir }
1815*cdf0e10cSrcweir 
1816*cdf0e10cSrcweir sal_Int16 implGetDateMonth( double aDate )
1817*cdf0e10cSrcweir {
1818*cdf0e10cSrcweir 	Date aRefDate( 1,1,1900 );
1819*cdf0e10cSrcweir 	long nDays = (long)aDate;
1820*cdf0e10cSrcweir 	nDays -= 2; // normieren: 1.1.1900 => 0.0
1821*cdf0e10cSrcweir 	aRefDate += nDays;
1822*cdf0e10cSrcweir 	sal_Int16 nRet = (sal_Int16)( aRefDate.GetMonth() );
1823*cdf0e10cSrcweir     return nRet;
1824*cdf0e10cSrcweir }
1825*cdf0e10cSrcweir 
1826*cdf0e10cSrcweir sal_Int16 implGetDateYear( double aDate )
1827*cdf0e10cSrcweir {
1828*cdf0e10cSrcweir 	Date aRefDate( 1,1,1900 );
1829*cdf0e10cSrcweir 	long nDays = (long) aDate;
1830*cdf0e10cSrcweir 	nDays -= 2; // normieren: 1.1.1900 => 0.0
1831*cdf0e10cSrcweir 	aRefDate += nDays;
1832*cdf0e10cSrcweir 	sal_Int16 nRet = (sal_Int16)( aRefDate.GetYear() );
1833*cdf0e10cSrcweir     return nRet;
1834*cdf0e10cSrcweir }
1835*cdf0e10cSrcweir 
1836*cdf0e10cSrcweir sal_Bool implDateSerial( sal_Int16 nYear, sal_Int16 nMonth, sal_Int16 nDay, double& rdRet )
1837*cdf0e10cSrcweir {
1838*cdf0e10cSrcweir 	if ( nYear < 30 && SbiRuntime::isVBAEnabled() )
1839*cdf0e10cSrcweir 		nYear += 2000;
1840*cdf0e10cSrcweir 	else if ( nYear < 100 )
1841*cdf0e10cSrcweir 		nYear += 1900;
1842*cdf0e10cSrcweir 	Date aCurDate( nDay, nMonth, nYear );
1843*cdf0e10cSrcweir 	if ((nYear < 100 || nYear > 9999) )
1844*cdf0e10cSrcweir 	{
1845*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
1846*cdf0e10cSrcweir 		return sal_False;
1847*cdf0e10cSrcweir 	}
1848*cdf0e10cSrcweir 	if ( !SbiRuntime::isVBAEnabled() )
1849*cdf0e10cSrcweir 	{
1850*cdf0e10cSrcweir 		if ( (nMonth < 1 || nMonth > 12 )||
1851*cdf0e10cSrcweir 		(nDay < 1 || nDay > 31 ) )
1852*cdf0e10cSrcweir 		{
1853*cdf0e10cSrcweir 			StarBASIC::Error( SbERR_BAD_ARGUMENT );
1854*cdf0e10cSrcweir 			return sal_False;
1855*cdf0e10cSrcweir 		}
1856*cdf0e10cSrcweir 	}
1857*cdf0e10cSrcweir 	else
1858*cdf0e10cSrcweir 	{
1859*cdf0e10cSrcweir 		// grab the year & month
1860*cdf0e10cSrcweir 		aCurDate = Date( 1, (( nMonth % 12 ) > 0 ) ? ( nMonth % 12 ) : 12 + ( nMonth % 12 ), nYear );
1861*cdf0e10cSrcweir 
1862*cdf0e10cSrcweir 		// adjust year based on month value
1863*cdf0e10cSrcweir 		// e.g. 2000, 0, xx = 1999, 12, xx ( or December of the previous year )
1864*cdf0e10cSrcweir 		//		2000, 13, xx = 2001, 1, xx ( or January of the following year )
1865*cdf0e10cSrcweir 		if( ( nMonth < 1 ) || ( nMonth > 12 ) )
1866*cdf0e10cSrcweir 		{
1867*cdf0e10cSrcweir 			// inacurrate around leap year, don't use days to calculate,
1868*cdf0e10cSrcweir 			// just modify the months directory
1869*cdf0e10cSrcweir 			sal_Int16 nYearAdj = ( nMonth /12 ); // default to positive months inputed
1870*cdf0e10cSrcweir 			if ( nMonth <=0 )
1871*cdf0e10cSrcweir 				nYearAdj = ( ( nMonth -12 ) / 12 );
1872*cdf0e10cSrcweir 			aCurDate.SetYear( aCurDate.GetYear() + nYearAdj );
1873*cdf0e10cSrcweir 		}
1874*cdf0e10cSrcweir 
1875*cdf0e10cSrcweir 		// adjust day value,
1876*cdf0e10cSrcweir 		// e.g. 2000, 2, 0 = 2000, 1, 31 or the last day of the previous month
1877*cdf0e10cSrcweir 		//		2000, 1, 32 = 2000, 2, 1 or the first day of the following month
1878*cdf0e10cSrcweir 		if( ( nDay < 1 ) || ( nDay > aCurDate.GetDaysInMonth() ) )
1879*cdf0e10cSrcweir 			aCurDate += nDay - 1;
1880*cdf0e10cSrcweir 		else
1881*cdf0e10cSrcweir 			aCurDate.SetDay( nDay );
1882*cdf0e10cSrcweir 	}
1883*cdf0e10cSrcweir 
1884*cdf0e10cSrcweir 	long nDiffDays = GetDayDiff( aCurDate );
1885*cdf0e10cSrcweir     rdRet = (double)nDiffDays;
1886*cdf0e10cSrcweir     return sal_True;
1887*cdf0e10cSrcweir }
1888*cdf0e10cSrcweir 
1889*cdf0e10cSrcweir // Function to convert date to ISO 8601 date format
1890*cdf0e10cSrcweir RTLFUNC(CDateToIso)
1891*cdf0e10cSrcweir {
1892*cdf0e10cSrcweir     (void)pBasic;
1893*cdf0e10cSrcweir     (void)bWrite;
1894*cdf0e10cSrcweir 
1895*cdf0e10cSrcweir 	if ( rPar.Count() == 2 )
1896*cdf0e10cSrcweir 	{
1897*cdf0e10cSrcweir         double aDate = rPar.Get(1)->GetDate();
1898*cdf0e10cSrcweir 
1899*cdf0e10cSrcweir         char Buffer[9];
1900*cdf0e10cSrcweir         snprintf( Buffer, sizeof( Buffer ), "%04d%02d%02d",
1901*cdf0e10cSrcweir             implGetDateYear( aDate ),
1902*cdf0e10cSrcweir             implGetDateMonth( aDate ),
1903*cdf0e10cSrcweir             implGetDateDay( aDate ) );
1904*cdf0e10cSrcweir 		String aRetStr = String::CreateFromAscii( Buffer );
1905*cdf0e10cSrcweir         rPar.Get(0)->PutString( aRetStr );
1906*cdf0e10cSrcweir 	}
1907*cdf0e10cSrcweir 	else
1908*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
1909*cdf0e10cSrcweir }
1910*cdf0e10cSrcweir 
1911*cdf0e10cSrcweir // Function to convert date from ISO 8601 date format
1912*cdf0e10cSrcweir RTLFUNC(CDateFromIso)
1913*cdf0e10cSrcweir {
1914*cdf0e10cSrcweir     (void)pBasic;
1915*cdf0e10cSrcweir     (void)bWrite;
1916*cdf0e10cSrcweir 
1917*cdf0e10cSrcweir 	if ( rPar.Count() == 2 )
1918*cdf0e10cSrcweir 	{
1919*cdf0e10cSrcweir 		String aStr = rPar.Get(1)->GetString();
1920*cdf0e10cSrcweir         sal_Int16 iMonthStart = aStr.Len() - 4;
1921*cdf0e10cSrcweir         String aYearStr  = aStr.Copy( 0, iMonthStart );
1922*cdf0e10cSrcweir         String aMonthStr = aStr.Copy( iMonthStart, 2 );
1923*cdf0e10cSrcweir         String aDayStr   = aStr.Copy( iMonthStart+2, 2 );
1924*cdf0e10cSrcweir 
1925*cdf0e10cSrcweir         double dDate;
1926*cdf0e10cSrcweir         if( implDateSerial( (sal_Int16)aYearStr.ToInt32(),
1927*cdf0e10cSrcweir             (sal_Int16)aMonthStr.ToInt32(), (sal_Int16)aDayStr.ToInt32(), dDate ) )
1928*cdf0e10cSrcweir         {
1929*cdf0e10cSrcweir     	    rPar.Get(0)->PutDate( dDate );
1930*cdf0e10cSrcweir         }
1931*cdf0e10cSrcweir 	}
1932*cdf0e10cSrcweir 	else
1933*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
1934*cdf0e10cSrcweir }
1935*cdf0e10cSrcweir 
1936*cdf0e10cSrcweir RTLFUNC(DateSerial)
1937*cdf0e10cSrcweir {
1938*cdf0e10cSrcweir     (void)pBasic;
1939*cdf0e10cSrcweir     (void)bWrite;
1940*cdf0e10cSrcweir 
1941*cdf0e10cSrcweir 	if ( rPar.Count() < 4 )
1942*cdf0e10cSrcweir 	{
1943*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
1944*cdf0e10cSrcweir 		return;
1945*cdf0e10cSrcweir 	}
1946*cdf0e10cSrcweir 	sal_Int16 nYear = rPar.Get(1)->GetInteger();
1947*cdf0e10cSrcweir 	sal_Int16 nMonth = rPar.Get(2)->GetInteger();
1948*cdf0e10cSrcweir 	sal_Int16 nDay = rPar.Get(3)->GetInteger();
1949*cdf0e10cSrcweir 
1950*cdf0e10cSrcweir     double dDate;
1951*cdf0e10cSrcweir     if( implDateSerial( nYear, nMonth, nDay, dDate ) )
1952*cdf0e10cSrcweir     	rPar.Get(0)->PutDate( dDate );
1953*cdf0e10cSrcweir }
1954*cdf0e10cSrcweir 
1955*cdf0e10cSrcweir RTLFUNC(TimeSerial)
1956*cdf0e10cSrcweir {
1957*cdf0e10cSrcweir     (void)pBasic;
1958*cdf0e10cSrcweir     (void)bWrite;
1959*cdf0e10cSrcweir 
1960*cdf0e10cSrcweir 	if ( rPar.Count() < 4 )
1961*cdf0e10cSrcweir 	{
1962*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
1963*cdf0e10cSrcweir 		return;
1964*cdf0e10cSrcweir 	}
1965*cdf0e10cSrcweir 	sal_Int16 nHour = rPar.Get(1)->GetInteger();
1966*cdf0e10cSrcweir 	if ( nHour == 24 )
1967*cdf0e10cSrcweir 		nHour = 0;                      // Wegen UNO DateTimes, die bis 24 Uhr gehen
1968*cdf0e10cSrcweir 	sal_Int16 nMinute = rPar.Get(2)->GetInteger();
1969*cdf0e10cSrcweir 	sal_Int16 nSecond = rPar.Get(3)->GetInteger();
1970*cdf0e10cSrcweir 	if ((nHour < 0 || nHour > 23)   ||
1971*cdf0e10cSrcweir 		(nMinute < 0 || nMinute > 59 )	||
1972*cdf0e10cSrcweir 		(nSecond < 0 || nSecond > 59 ))
1973*cdf0e10cSrcweir 	{
1974*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
1975*cdf0e10cSrcweir 		return;
1976*cdf0e10cSrcweir 	}
1977*cdf0e10cSrcweir 
1978*cdf0e10cSrcweir 	sal_Int32 nSeconds = nHour;
1979*cdf0e10cSrcweir 	nSeconds *= 3600;
1980*cdf0e10cSrcweir 	nSeconds += nMinute * 60;
1981*cdf0e10cSrcweir 	nSeconds += nSecond;
1982*cdf0e10cSrcweir 	double nDays = ((double)nSeconds) / (double)(86400.0);
1983*cdf0e10cSrcweir 	rPar.Get(0)->PutDate( nDays ); // JSM
1984*cdf0e10cSrcweir }
1985*cdf0e10cSrcweir 
1986*cdf0e10cSrcweir RTLFUNC(DateValue)
1987*cdf0e10cSrcweir {
1988*cdf0e10cSrcweir     (void)pBasic;
1989*cdf0e10cSrcweir     (void)bWrite;
1990*cdf0e10cSrcweir 
1991*cdf0e10cSrcweir 	if ( rPar.Count() < 2 )
1992*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
1993*cdf0e10cSrcweir 	else
1994*cdf0e10cSrcweir 	{
1995*cdf0e10cSrcweir 		// #39629 pINST pruefen, kann aus URL-Zeile gerufen werden
1996*cdf0e10cSrcweir 		SvNumberFormatter* pFormatter = NULL;
1997*cdf0e10cSrcweir 		if( pINST )
1998*cdf0e10cSrcweir 			pFormatter = pINST->GetNumberFormatter();
1999*cdf0e10cSrcweir 		else
2000*cdf0e10cSrcweir 		{
2001*cdf0e10cSrcweir 			sal_uInt32 n;	// Dummy
2002*cdf0e10cSrcweir 			SbiInstance::PrepareNumberFormatter( pFormatter, n, n, n );
2003*cdf0e10cSrcweir 		}
2004*cdf0e10cSrcweir 
2005*cdf0e10cSrcweir 		sal_uInt32 nIndex;
2006*cdf0e10cSrcweir 		double fResult;
2007*cdf0e10cSrcweir 		String aStr( rPar.Get(1)->GetString() );
2008*cdf0e10cSrcweir 		sal_Bool bSuccess = pFormatter->IsNumberFormat( aStr, nIndex, fResult );
2009*cdf0e10cSrcweir 		short nType = pFormatter->GetType( nIndex );
2010*cdf0e10cSrcweir 
2011*cdf0e10cSrcweir 		// DateValue("February 12, 1969") raises error if the system locale is not en_US
2012*cdf0e10cSrcweir 		// by using SbiInstance::GetNumberFormatter.
2013*cdf0e10cSrcweir 		// It seems that both locale number formatter and English number formatter
2014*cdf0e10cSrcweir 		// are supported in Visual Basic.
2015*cdf0e10cSrcweir 		LanguageType eLangType = GetpApp()->GetSettings().GetLanguage();
2016*cdf0e10cSrcweir         if( !bSuccess && ( eLangType != LANGUAGE_ENGLISH_US ) )
2017*cdf0e10cSrcweir 		{
2018*cdf0e10cSrcweir 			// Create a new SvNumberFormatter by using LANGUAGE_ENGLISH to get the date value;
2019*cdf0e10cSrcweir 			com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
2020*cdf0e10cSrcweir 				xFactory = comphelper::getProcessServiceFactory();
2021*cdf0e10cSrcweir 			SvNumberFormatter aFormatter( xFactory, LANGUAGE_ENGLISH_US );
2022*cdf0e10cSrcweir 			bSuccess = aFormatter.IsNumberFormat( aStr, nIndex, fResult );
2023*cdf0e10cSrcweir 			nType = aFormatter.GetType( nIndex );
2024*cdf0e10cSrcweir 		}
2025*cdf0e10cSrcweir 
2026*cdf0e10cSrcweir 		if(bSuccess && (nType==NUMBERFORMAT_DATE || nType==NUMBERFORMAT_DATETIME))
2027*cdf0e10cSrcweir 		{
2028*cdf0e10cSrcweir 			if ( nType == NUMBERFORMAT_DATETIME )
2029*cdf0e10cSrcweir 			{
2030*cdf0e10cSrcweir 				// Zeit abschneiden
2031*cdf0e10cSrcweir 				if ( fResult  > 0.0 )
2032*cdf0e10cSrcweir 					fResult = floor( fResult );
2033*cdf0e10cSrcweir 				else
2034*cdf0e10cSrcweir 					fResult = ceil( fResult );
2035*cdf0e10cSrcweir 			}
2036*cdf0e10cSrcweir 			// fResult += 2.0; // Anpassung  StarCalcFormatter
2037*cdf0e10cSrcweir 			rPar.Get(0)->PutDate( fResult ); // JSM
2038*cdf0e10cSrcweir 		}
2039*cdf0e10cSrcweir 		else
2040*cdf0e10cSrcweir 			StarBASIC::Error( SbERR_CONVERSION );
2041*cdf0e10cSrcweir 
2042*cdf0e10cSrcweir 		// #39629 pFormatter kann selbst angefordert sein
2043*cdf0e10cSrcweir 		if( !pINST )
2044*cdf0e10cSrcweir 			delete pFormatter;
2045*cdf0e10cSrcweir 	}
2046*cdf0e10cSrcweir }
2047*cdf0e10cSrcweir 
2048*cdf0e10cSrcweir RTLFUNC(TimeValue)
2049*cdf0e10cSrcweir {
2050*cdf0e10cSrcweir     (void)pBasic;
2051*cdf0e10cSrcweir     (void)bWrite;
2052*cdf0e10cSrcweir 
2053*cdf0e10cSrcweir 	if ( rPar.Count() < 2 )
2054*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
2055*cdf0e10cSrcweir 	else
2056*cdf0e10cSrcweir 	{
2057*cdf0e10cSrcweir 		// #39629 pINST pruefen, kann aus URL-Zeile gerufen werden
2058*cdf0e10cSrcweir 		SvNumberFormatter* pFormatter = NULL;
2059*cdf0e10cSrcweir 		if( pINST )
2060*cdf0e10cSrcweir 			pFormatter = pINST->GetNumberFormatter();
2061*cdf0e10cSrcweir 		else
2062*cdf0e10cSrcweir 		{
2063*cdf0e10cSrcweir 			sal_uInt32 n;	// Dummy
2064*cdf0e10cSrcweir 			SbiInstance::PrepareNumberFormatter( pFormatter, n, n, n );
2065*cdf0e10cSrcweir 		}
2066*cdf0e10cSrcweir 
2067*cdf0e10cSrcweir 		sal_uInt32 nIndex;
2068*cdf0e10cSrcweir 		double fResult;
2069*cdf0e10cSrcweir 		sal_Bool bSuccess = pFormatter->IsNumberFormat( rPar.Get(1)->GetString(),
2070*cdf0e10cSrcweir 												   nIndex, fResult );
2071*cdf0e10cSrcweir 		short nType = pFormatter->GetType(nIndex);
2072*cdf0e10cSrcweir 		if(bSuccess && (nType==NUMBERFORMAT_TIME||nType==NUMBERFORMAT_DATETIME))
2073*cdf0e10cSrcweir 		{
2074*cdf0e10cSrcweir 			if ( nType == NUMBERFORMAT_DATETIME )
2075*cdf0e10cSrcweir 				// Tage abschneiden
2076*cdf0e10cSrcweir 				fResult = fmod( fResult, 1 );
2077*cdf0e10cSrcweir 			rPar.Get(0)->PutDate( fResult ); // JSM
2078*cdf0e10cSrcweir 		}
2079*cdf0e10cSrcweir 		else
2080*cdf0e10cSrcweir 			StarBASIC::Error( SbERR_CONVERSION );
2081*cdf0e10cSrcweir 
2082*cdf0e10cSrcweir 		// #39629 pFormatter kann selbst angefordert sein
2083*cdf0e10cSrcweir 		if( !pINST )
2084*cdf0e10cSrcweir 			delete pFormatter;
2085*cdf0e10cSrcweir 	}
2086*cdf0e10cSrcweir }
2087*cdf0e10cSrcweir 
2088*cdf0e10cSrcweir RTLFUNC(Day)
2089*cdf0e10cSrcweir {
2090*cdf0e10cSrcweir     (void)pBasic;
2091*cdf0e10cSrcweir     (void)bWrite;
2092*cdf0e10cSrcweir 
2093*cdf0e10cSrcweir 	if ( rPar.Count() < 2 )
2094*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
2095*cdf0e10cSrcweir 	else
2096*cdf0e10cSrcweir 	{
2097*cdf0e10cSrcweir 		SbxVariableRef pArg = rPar.Get( 1 );
2098*cdf0e10cSrcweir 		double aDate = pArg->GetDate();
2099*cdf0e10cSrcweir 
2100*cdf0e10cSrcweir         sal_Int16 nDay = implGetDateDay( aDate );
2101*cdf0e10cSrcweir 		rPar.Get(0)->PutInteger( nDay );
2102*cdf0e10cSrcweir 	}
2103*cdf0e10cSrcweir }
2104*cdf0e10cSrcweir 
2105*cdf0e10cSrcweir RTLFUNC(Year)
2106*cdf0e10cSrcweir {
2107*cdf0e10cSrcweir     (void)pBasic;
2108*cdf0e10cSrcweir     (void)bWrite;
2109*cdf0e10cSrcweir 
2110*cdf0e10cSrcweir 	if ( rPar.Count() < 2 )
2111*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
2112*cdf0e10cSrcweir 	else
2113*cdf0e10cSrcweir 	{
2114*cdf0e10cSrcweir         sal_Int16 nYear = implGetDateYear( rPar.Get(1)->GetDate() );
2115*cdf0e10cSrcweir 		rPar.Get(0)->PutInteger( nYear );
2116*cdf0e10cSrcweir 	}
2117*cdf0e10cSrcweir }
2118*cdf0e10cSrcweir 
2119*cdf0e10cSrcweir sal_Int16 implGetHour( double dDate )
2120*cdf0e10cSrcweir {
2121*cdf0e10cSrcweir 	if( dDate < 0.0 )
2122*cdf0e10cSrcweir 		dDate *= -1.0;
2123*cdf0e10cSrcweir 	double nFrac = dDate - floor( dDate );
2124*cdf0e10cSrcweir 	nFrac *= 86400.0;
2125*cdf0e10cSrcweir 	sal_Int32 nSeconds = (sal_Int32)(nFrac + 0.5);
2126*cdf0e10cSrcweir 	sal_Int16 nHour = (sal_Int16)(nSeconds / 3600);
2127*cdf0e10cSrcweir     return nHour;
2128*cdf0e10cSrcweir }
2129*cdf0e10cSrcweir 
2130*cdf0e10cSrcweir RTLFUNC(Hour)
2131*cdf0e10cSrcweir {
2132*cdf0e10cSrcweir     (void)pBasic;
2133*cdf0e10cSrcweir     (void)bWrite;
2134*cdf0e10cSrcweir 
2135*cdf0e10cSrcweir 	if ( rPar.Count() < 2 )
2136*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
2137*cdf0e10cSrcweir 	else
2138*cdf0e10cSrcweir 	{
2139*cdf0e10cSrcweir 		double nArg = rPar.Get(1)->GetDate();
2140*cdf0e10cSrcweir 		sal_Int16 nHour = implGetHour( nArg );
2141*cdf0e10cSrcweir 		rPar.Get(0)->PutInteger( nHour );
2142*cdf0e10cSrcweir 	}
2143*cdf0e10cSrcweir }
2144*cdf0e10cSrcweir 
2145*cdf0e10cSrcweir sal_Int16 implGetMinute( double dDate )
2146*cdf0e10cSrcweir {
2147*cdf0e10cSrcweir 	if( dDate < 0.0 )
2148*cdf0e10cSrcweir 		dDate *= -1.0;
2149*cdf0e10cSrcweir 	double nFrac = dDate - floor( dDate );
2150*cdf0e10cSrcweir 	nFrac *= 86400.0;
2151*cdf0e10cSrcweir 	sal_Int32 nSeconds = (sal_Int32)(nFrac + 0.5);
2152*cdf0e10cSrcweir 	sal_Int16 nTemp = (sal_Int16)(nSeconds % 3600);
2153*cdf0e10cSrcweir 	sal_Int16 nMin = nTemp / 60;
2154*cdf0e10cSrcweir     return nMin;
2155*cdf0e10cSrcweir }
2156*cdf0e10cSrcweir 
2157*cdf0e10cSrcweir RTLFUNC(Minute)
2158*cdf0e10cSrcweir {
2159*cdf0e10cSrcweir     (void)pBasic;
2160*cdf0e10cSrcweir     (void)bWrite;
2161*cdf0e10cSrcweir 
2162*cdf0e10cSrcweir 	if ( rPar.Count() < 2 )
2163*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
2164*cdf0e10cSrcweir 	else
2165*cdf0e10cSrcweir 	{
2166*cdf0e10cSrcweir 		double nArg = rPar.Get(1)->GetDate();
2167*cdf0e10cSrcweir 		sal_Int16 nMin = implGetMinute( nArg );
2168*cdf0e10cSrcweir 		rPar.Get(0)->PutInteger( nMin );
2169*cdf0e10cSrcweir 	}
2170*cdf0e10cSrcweir }
2171*cdf0e10cSrcweir 
2172*cdf0e10cSrcweir RTLFUNC(Month)
2173*cdf0e10cSrcweir {
2174*cdf0e10cSrcweir     (void)pBasic;
2175*cdf0e10cSrcweir     (void)bWrite;
2176*cdf0e10cSrcweir 
2177*cdf0e10cSrcweir 	if ( rPar.Count() < 2 )
2178*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
2179*cdf0e10cSrcweir 	else
2180*cdf0e10cSrcweir 	{
2181*cdf0e10cSrcweir         sal_Int16 nMonth = implGetDateMonth( rPar.Get(1)->GetDate() );
2182*cdf0e10cSrcweir 		rPar.Get(0)->PutInteger( nMonth );
2183*cdf0e10cSrcweir 	}
2184*cdf0e10cSrcweir }
2185*cdf0e10cSrcweir 
2186*cdf0e10cSrcweir sal_Int16 implGetSecond( double dDate )
2187*cdf0e10cSrcweir {
2188*cdf0e10cSrcweir 	if( dDate < 0.0 )
2189*cdf0e10cSrcweir 		dDate *= -1.0;
2190*cdf0e10cSrcweir 	double nFrac = dDate - floor( dDate );
2191*cdf0e10cSrcweir 	nFrac *= 86400.0;
2192*cdf0e10cSrcweir 	sal_Int32 nSeconds = (sal_Int32)(nFrac + 0.5);
2193*cdf0e10cSrcweir 	sal_Int16 nTemp = (sal_Int16)(nSeconds / 3600);
2194*cdf0e10cSrcweir 	nSeconds -= nTemp * 3600;
2195*cdf0e10cSrcweir 	nTemp = (sal_Int16)(nSeconds / 60);
2196*cdf0e10cSrcweir 	nSeconds -= nTemp * 60;
2197*cdf0e10cSrcweir 
2198*cdf0e10cSrcweir 	sal_Int16 nRet = (sal_Int16)nSeconds;
2199*cdf0e10cSrcweir     return nRet;
2200*cdf0e10cSrcweir }
2201*cdf0e10cSrcweir 
2202*cdf0e10cSrcweir RTLFUNC(Second)
2203*cdf0e10cSrcweir {
2204*cdf0e10cSrcweir     (void)pBasic;
2205*cdf0e10cSrcweir     (void)bWrite;
2206*cdf0e10cSrcweir 
2207*cdf0e10cSrcweir 	if ( rPar.Count() < 2 )
2208*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
2209*cdf0e10cSrcweir 	else
2210*cdf0e10cSrcweir 	{
2211*cdf0e10cSrcweir 		double nArg = rPar.Get(1)->GetDate();
2212*cdf0e10cSrcweir 		sal_Int16 nSecond = implGetSecond( nArg );
2213*cdf0e10cSrcweir 		rPar.Get(0)->PutInteger( nSecond );
2214*cdf0e10cSrcweir 	}
2215*cdf0e10cSrcweir }
2216*cdf0e10cSrcweir 
2217*cdf0e10cSrcweir double Now_Impl()
2218*cdf0e10cSrcweir {
2219*cdf0e10cSrcweir 	Date aDate;
2220*cdf0e10cSrcweir 	Time aTime;
2221*cdf0e10cSrcweir 	double aSerial = (double)GetDayDiff( aDate );
2222*cdf0e10cSrcweir 	long nSeconds = aTime.GetHour();
2223*cdf0e10cSrcweir 	nSeconds *= 3600;
2224*cdf0e10cSrcweir 	nSeconds += aTime.GetMin() * 60;
2225*cdf0e10cSrcweir 	nSeconds += aTime.GetSec();
2226*cdf0e10cSrcweir 	double nDays = ((double)nSeconds) / (double)(24.0*3600.0);
2227*cdf0e10cSrcweir 	aSerial += nDays;
2228*cdf0e10cSrcweir 	return aSerial;
2229*cdf0e10cSrcweir }
2230*cdf0e10cSrcweir 
2231*cdf0e10cSrcweir // Date Now(void)
2232*cdf0e10cSrcweir 
2233*cdf0e10cSrcweir RTLFUNC(Now)
2234*cdf0e10cSrcweir {
2235*cdf0e10cSrcweir     	(void)pBasic;
2236*cdf0e10cSrcweir     	(void)bWrite;
2237*cdf0e10cSrcweir 	rPar.Get(0)->PutDate( Now_Impl() );
2238*cdf0e10cSrcweir }
2239*cdf0e10cSrcweir 
2240*cdf0e10cSrcweir // Date Time(void)
2241*cdf0e10cSrcweir 
2242*cdf0e10cSrcweir RTLFUNC(Time)
2243*cdf0e10cSrcweir {
2244*cdf0e10cSrcweir     (void)pBasic;
2245*cdf0e10cSrcweir 
2246*cdf0e10cSrcweir 	if ( !bWrite )
2247*cdf0e10cSrcweir 	{
2248*cdf0e10cSrcweir 		Time aTime;
2249*cdf0e10cSrcweir 		SbxVariable* pMeth = rPar.Get( 0 );
2250*cdf0e10cSrcweir 		String aRes;
2251*cdf0e10cSrcweir 		if( pMeth->IsFixed() )
2252*cdf0e10cSrcweir 		{
2253*cdf0e10cSrcweir 			// Time$: hh:mm:ss
2254*cdf0e10cSrcweir 			char buf[ 20 ];
2255*cdf0e10cSrcweir             snprintf( buf, sizeof(buf), "%02d:%02d:%02d",
2256*cdf0e10cSrcweir 				aTime.GetHour(), aTime.GetMin(), aTime.GetSec() );
2257*cdf0e10cSrcweir 			aRes = String::CreateFromAscii( buf );
2258*cdf0e10cSrcweir 		}
2259*cdf0e10cSrcweir 		else
2260*cdf0e10cSrcweir 		{
2261*cdf0e10cSrcweir 			// Time: system dependent
2262*cdf0e10cSrcweir 			long nSeconds=aTime.GetHour();
2263*cdf0e10cSrcweir 			nSeconds *= 3600;
2264*cdf0e10cSrcweir 			nSeconds += aTime.GetMin() * 60;
2265*cdf0e10cSrcweir 			nSeconds += aTime.GetSec();
2266*cdf0e10cSrcweir 			double nDays = (double)nSeconds * ( 1.0 / (24.0*3600.0) );
2267*cdf0e10cSrcweir 			Color* pCol;
2268*cdf0e10cSrcweir 
2269*cdf0e10cSrcweir 			// #39629 pINST pruefen, kann aus URL-Zeile gerufen werden
2270*cdf0e10cSrcweir 			SvNumberFormatter* pFormatter = NULL;
2271*cdf0e10cSrcweir 			sal_uInt32 nIndex;
2272*cdf0e10cSrcweir 			if( pINST )
2273*cdf0e10cSrcweir 			{
2274*cdf0e10cSrcweir 				pFormatter = pINST->GetNumberFormatter();
2275*cdf0e10cSrcweir 				nIndex = pINST->GetStdTimeIdx();
2276*cdf0e10cSrcweir 			}
2277*cdf0e10cSrcweir 			else
2278*cdf0e10cSrcweir 			{
2279*cdf0e10cSrcweir 				sal_uInt32 n;	// Dummy
2280*cdf0e10cSrcweir 				SbiInstance::PrepareNumberFormatter( pFormatter, n, nIndex, n );
2281*cdf0e10cSrcweir 			}
2282*cdf0e10cSrcweir 
2283*cdf0e10cSrcweir 			pFormatter->GetOutputString( nDays, nIndex, aRes, &pCol );
2284*cdf0e10cSrcweir 
2285*cdf0e10cSrcweir 			// #39629 pFormatter kann selbst angefordert sein
2286*cdf0e10cSrcweir 			if( !pINST )
2287*cdf0e10cSrcweir 				delete pFormatter;
2288*cdf0e10cSrcweir 		}
2289*cdf0e10cSrcweir 		pMeth->PutString( aRes );
2290*cdf0e10cSrcweir 	}
2291*cdf0e10cSrcweir 	else
2292*cdf0e10cSrcweir 	{
2293*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_NOT_IMPLEMENTED );
2294*cdf0e10cSrcweir 	}
2295*cdf0e10cSrcweir }
2296*cdf0e10cSrcweir 
2297*cdf0e10cSrcweir RTLFUNC(Timer)
2298*cdf0e10cSrcweir {
2299*cdf0e10cSrcweir     (void)pBasic;
2300*cdf0e10cSrcweir     (void)bWrite;
2301*cdf0e10cSrcweir 
2302*cdf0e10cSrcweir 	Time aTime;
2303*cdf0e10cSrcweir 	long nSeconds = aTime.GetHour();
2304*cdf0e10cSrcweir 	nSeconds *= 3600;
2305*cdf0e10cSrcweir 	nSeconds += aTime.GetMin() * 60;
2306*cdf0e10cSrcweir 	nSeconds += aTime.GetSec();
2307*cdf0e10cSrcweir 	rPar.Get(0)->PutDate( (double)nSeconds );
2308*cdf0e10cSrcweir }
2309*cdf0e10cSrcweir 
2310*cdf0e10cSrcweir 
2311*cdf0e10cSrcweir RTLFUNC(Date)
2312*cdf0e10cSrcweir {
2313*cdf0e10cSrcweir     (void)pBasic;
2314*cdf0e10cSrcweir     (void)bWrite;
2315*cdf0e10cSrcweir 
2316*cdf0e10cSrcweir 	if ( !bWrite )
2317*cdf0e10cSrcweir 	{
2318*cdf0e10cSrcweir 		Date aToday;
2319*cdf0e10cSrcweir 		double nDays = (double)GetDayDiff( aToday );
2320*cdf0e10cSrcweir 		SbxVariable* pMeth = rPar.Get( 0 );
2321*cdf0e10cSrcweir 		if( pMeth->IsString() )
2322*cdf0e10cSrcweir 		{
2323*cdf0e10cSrcweir 			String aRes;
2324*cdf0e10cSrcweir 			Color* pCol;
2325*cdf0e10cSrcweir 
2326*cdf0e10cSrcweir 			// #39629 pINST pruefen, kann aus URL-Zeile gerufen werden
2327*cdf0e10cSrcweir 			SvNumberFormatter* pFormatter = NULL;
2328*cdf0e10cSrcweir 			sal_uInt32 nIndex;
2329*cdf0e10cSrcweir 			if( pINST )
2330*cdf0e10cSrcweir 			{
2331*cdf0e10cSrcweir 				pFormatter = pINST->GetNumberFormatter();
2332*cdf0e10cSrcweir 				nIndex = pINST->GetStdDateIdx();
2333*cdf0e10cSrcweir 			}
2334*cdf0e10cSrcweir 			else
2335*cdf0e10cSrcweir 			{
2336*cdf0e10cSrcweir 				sal_uInt32 n;	// Dummy
2337*cdf0e10cSrcweir 				SbiInstance::PrepareNumberFormatter( pFormatter, nIndex, n, n );
2338*cdf0e10cSrcweir 			}
2339*cdf0e10cSrcweir 
2340*cdf0e10cSrcweir 			pFormatter->GetOutputString( nDays, nIndex, aRes, &pCol );
2341*cdf0e10cSrcweir 			pMeth->PutString( aRes );
2342*cdf0e10cSrcweir 
2343*cdf0e10cSrcweir 			// #39629 pFormatter kann selbst angefordert sein
2344*cdf0e10cSrcweir 			if( !pINST )
2345*cdf0e10cSrcweir 				delete pFormatter;
2346*cdf0e10cSrcweir 		}
2347*cdf0e10cSrcweir 		else
2348*cdf0e10cSrcweir 			pMeth->PutDate( nDays );
2349*cdf0e10cSrcweir 	}
2350*cdf0e10cSrcweir 	else
2351*cdf0e10cSrcweir 	{
2352*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_NOT_IMPLEMENTED );
2353*cdf0e10cSrcweir 	}
2354*cdf0e10cSrcweir }
2355*cdf0e10cSrcweir 
2356*cdf0e10cSrcweir RTLFUNC(IsArray)
2357*cdf0e10cSrcweir {
2358*cdf0e10cSrcweir     (void)pBasic;
2359*cdf0e10cSrcweir     (void)bWrite;
2360*cdf0e10cSrcweir 
2361*cdf0e10cSrcweir 	if ( rPar.Count() < 2 )
2362*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
2363*cdf0e10cSrcweir 	else
2364*cdf0e10cSrcweir 		rPar.Get(0)->PutBool((rPar.Get(1)->GetType() & SbxARRAY) ? sal_True : sal_False );
2365*cdf0e10cSrcweir }
2366*cdf0e10cSrcweir 
2367*cdf0e10cSrcweir RTLFUNC(IsObject)
2368*cdf0e10cSrcweir {
2369*cdf0e10cSrcweir     (void)pBasic;
2370*cdf0e10cSrcweir     (void)bWrite;
2371*cdf0e10cSrcweir 
2372*cdf0e10cSrcweir 	if ( rPar.Count() < 2 )
2373*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
2374*cdf0e10cSrcweir 	else
2375*cdf0e10cSrcweir     {
2376*cdf0e10cSrcweir     	SbxVariable* pVar = rPar.Get(1);
2377*cdf0e10cSrcweir 	    SbxBase* pObj = (SbxBase*)pVar->GetObject();
2378*cdf0e10cSrcweir 
2379*cdf0e10cSrcweir 		// #100385: GetObject can result in an error, so reset it
2380*cdf0e10cSrcweir 		SbxBase::ResetError();
2381*cdf0e10cSrcweir 
2382*cdf0e10cSrcweir         SbUnoClass* pUnoClass;
2383*cdf0e10cSrcweir         sal_Bool bObject;
2384*cdf0e10cSrcweir 	    if( pObj &&  NULL != ( pUnoClass=PTR_CAST(SbUnoClass,pObj) ) )
2385*cdf0e10cSrcweir         {
2386*cdf0e10cSrcweir             bObject = pUnoClass->getUnoClass().is();
2387*cdf0e10cSrcweir         }
2388*cdf0e10cSrcweir         else
2389*cdf0e10cSrcweir         {
2390*cdf0e10cSrcweir             bObject = pVar->IsObject();
2391*cdf0e10cSrcweir         }
2392*cdf0e10cSrcweir 		rPar.Get( 0 )->PutBool( bObject );
2393*cdf0e10cSrcweir     }
2394*cdf0e10cSrcweir }
2395*cdf0e10cSrcweir 
2396*cdf0e10cSrcweir RTLFUNC(IsDate)
2397*cdf0e10cSrcweir {
2398*cdf0e10cSrcweir     (void)pBasic;
2399*cdf0e10cSrcweir     (void)bWrite;
2400*cdf0e10cSrcweir 
2401*cdf0e10cSrcweir 	if ( rPar.Count() < 2 )
2402*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
2403*cdf0e10cSrcweir 	else
2404*cdf0e10cSrcweir 	{
2405*cdf0e10cSrcweir 		// #46134 Nur String wird konvertiert, andere Typen ergeben sal_False
2406*cdf0e10cSrcweir 		SbxVariableRef xArg = rPar.Get( 1 );
2407*cdf0e10cSrcweir 		SbxDataType eType = xArg->GetType();
2408*cdf0e10cSrcweir 		sal_Bool bDate = sal_False;
2409*cdf0e10cSrcweir 
2410*cdf0e10cSrcweir 		if( eType == SbxDATE )
2411*cdf0e10cSrcweir 		{
2412*cdf0e10cSrcweir 			bDate = sal_True;
2413*cdf0e10cSrcweir 		}
2414*cdf0e10cSrcweir 		else if( eType == SbxSTRING )
2415*cdf0e10cSrcweir 		{
2416*cdf0e10cSrcweir 			// Error loeschen
2417*cdf0e10cSrcweir 			SbxError nPrevError = SbxBase::GetError();
2418*cdf0e10cSrcweir 			SbxBase::ResetError();
2419*cdf0e10cSrcweir 
2420*cdf0e10cSrcweir 			// Konvertierung des Parameters nach SbxDATE erzwingen
2421*cdf0e10cSrcweir 			xArg->SbxValue::GetDate();
2422*cdf0e10cSrcweir 
2423*cdf0e10cSrcweir 			// Bei Fehler ist es kein Date
2424*cdf0e10cSrcweir 			bDate = !SbxBase::IsError();
2425*cdf0e10cSrcweir 
2426*cdf0e10cSrcweir 			// Error-Situation wiederherstellen
2427*cdf0e10cSrcweir 			SbxBase::ResetError();
2428*cdf0e10cSrcweir 			SbxBase::SetError( nPrevError );
2429*cdf0e10cSrcweir 		}
2430*cdf0e10cSrcweir 		rPar.Get( 0 )->PutBool( bDate );
2431*cdf0e10cSrcweir 	}
2432*cdf0e10cSrcweir }
2433*cdf0e10cSrcweir 
2434*cdf0e10cSrcweir RTLFUNC(IsEmpty)
2435*cdf0e10cSrcweir {
2436*cdf0e10cSrcweir     (void)pBasic;
2437*cdf0e10cSrcweir     (void)bWrite;
2438*cdf0e10cSrcweir 
2439*cdf0e10cSrcweir 	if ( rPar.Count() < 2 )
2440*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
2441*cdf0e10cSrcweir 	else
2442*cdf0e10cSrcweir 		rPar.Get( 0 )->PutBool( rPar.Get(1)->IsEmpty() );
2443*cdf0e10cSrcweir }
2444*cdf0e10cSrcweir 
2445*cdf0e10cSrcweir RTLFUNC(IsError)
2446*cdf0e10cSrcweir {
2447*cdf0e10cSrcweir     (void)pBasic;
2448*cdf0e10cSrcweir     (void)bWrite;
2449*cdf0e10cSrcweir 
2450*cdf0e10cSrcweir 	if ( rPar.Count() < 2 )
2451*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
2452*cdf0e10cSrcweir 	else
2453*cdf0e10cSrcweir 		rPar.Get( 0 )->PutBool( rPar.Get(1)->IsErr() );
2454*cdf0e10cSrcweir }
2455*cdf0e10cSrcweir 
2456*cdf0e10cSrcweir RTLFUNC(IsNull)
2457*cdf0e10cSrcweir {
2458*cdf0e10cSrcweir     (void)pBasic;
2459*cdf0e10cSrcweir     (void)bWrite;
2460*cdf0e10cSrcweir 
2461*cdf0e10cSrcweir 	if ( rPar.Count() < 2 )
2462*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
2463*cdf0e10cSrcweir 	else
2464*cdf0e10cSrcweir 	{
2465*cdf0e10cSrcweir 		// #51475 Wegen Uno-Objekten auch true liefern,
2466*cdf0e10cSrcweir 		// wenn der pObj-Wert NULL ist
2467*cdf0e10cSrcweir 		SbxVariableRef pArg = rPar.Get( 1 );
2468*cdf0e10cSrcweir 		sal_Bool bNull = rPar.Get(1)->IsNull();
2469*cdf0e10cSrcweir 		if( !bNull && pArg->GetType() == SbxOBJECT )
2470*cdf0e10cSrcweir 		{
2471*cdf0e10cSrcweir 			SbxBase* pObj = pArg->GetObject();
2472*cdf0e10cSrcweir 			if( !pObj )
2473*cdf0e10cSrcweir 				bNull = sal_True;
2474*cdf0e10cSrcweir 		}
2475*cdf0e10cSrcweir 		rPar.Get( 0 )->PutBool( bNull );
2476*cdf0e10cSrcweir 	}
2477*cdf0e10cSrcweir }
2478*cdf0e10cSrcweir 
2479*cdf0e10cSrcweir RTLFUNC(IsNumeric)
2480*cdf0e10cSrcweir {
2481*cdf0e10cSrcweir     (void)pBasic;
2482*cdf0e10cSrcweir     (void)bWrite;
2483*cdf0e10cSrcweir 
2484*cdf0e10cSrcweir 	if ( rPar.Count() < 2 )
2485*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
2486*cdf0e10cSrcweir 	else
2487*cdf0e10cSrcweir 		rPar.Get( 0 )->PutBool( rPar.Get( 1 )->IsNumericRTL() );
2488*cdf0e10cSrcweir }
2489*cdf0e10cSrcweir 
2490*cdf0e10cSrcweir // Das machen wir auf die billige Tour
2491*cdf0e10cSrcweir 
2492*cdf0e10cSrcweir RTLFUNC(IsMissing)
2493*cdf0e10cSrcweir {
2494*cdf0e10cSrcweir     (void)pBasic;
2495*cdf0e10cSrcweir     (void)bWrite;
2496*cdf0e10cSrcweir 
2497*cdf0e10cSrcweir 	if ( rPar.Count() < 2 )
2498*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
2499*cdf0e10cSrcweir 	else
2500*cdf0e10cSrcweir 		// #57915 Missing wird durch Error angezeigt
2501*cdf0e10cSrcweir 		rPar.Get( 0 )->PutBool( rPar.Get(1)->IsErr() );
2502*cdf0e10cSrcweir }
2503*cdf0e10cSrcweir 
2504*cdf0e10cSrcweir // Dir( [Maske] [,Attrs] )
2505*cdf0e10cSrcweir // ToDo: Library-globaler Datenbereich fuer Dir-Objekt und Flags
2506*cdf0e10cSrcweir 
2507*cdf0e10cSrcweir 
2508*cdf0e10cSrcweir String getDirectoryPath( String aPathStr )
2509*cdf0e10cSrcweir {
2510*cdf0e10cSrcweir     String aRetStr;
2511*cdf0e10cSrcweir 
2512*cdf0e10cSrcweir     DirectoryItem aItem;
2513*cdf0e10cSrcweir     FileBase::RC nRet = DirectoryItem::get( aPathStr, aItem );
2514*cdf0e10cSrcweir 	if( nRet == FileBase::E_None )
2515*cdf0e10cSrcweir 	{
2516*cdf0e10cSrcweir 		FileStatus aFileStatus( FileStatusMask_Type );
2517*cdf0e10cSrcweir 		nRet = aItem.getFileStatus( aFileStatus );
2518*cdf0e10cSrcweir 		if( nRet == FileBase::E_None )
2519*cdf0e10cSrcweir 		{
2520*cdf0e10cSrcweir 			FileStatus::Type aType = aFileStatus.getFileType();
2521*cdf0e10cSrcweir 			if( isFolder( aType ) )
2522*cdf0e10cSrcweir             {
2523*cdf0e10cSrcweir         		aRetStr = aPathStr;
2524*cdf0e10cSrcweir             }
2525*cdf0e10cSrcweir             else if( aType == FileStatus::Link )
2526*cdf0e10cSrcweir             {
2527*cdf0e10cSrcweir         		FileStatus aFileStatus2( FileStatusMask_LinkTargetURL );
2528*cdf0e10cSrcweir         		nRet = aItem.getFileStatus( aFileStatus2 );
2529*cdf0e10cSrcweir 		        if( nRet == FileBase::E_None )
2530*cdf0e10cSrcweir                     aRetStr = getDirectoryPath( aFileStatus2.getLinkTargetURL() );
2531*cdf0e10cSrcweir             }
2532*cdf0e10cSrcweir 		}
2533*cdf0e10cSrcweir     }
2534*cdf0e10cSrcweir     return aRetStr;
2535*cdf0e10cSrcweir }
2536*cdf0e10cSrcweir 
2537*cdf0e10cSrcweir // Function looks for wildcards, removes them and always returns the pure path
2538*cdf0e10cSrcweir String implSetupWildcard( const String& rFileParam, SbiRTLData* pRTLData )
2539*cdf0e10cSrcweir {
2540*cdf0e10cSrcweir     static String aAsterisk = String::CreateFromAscii( "*" );
2541*cdf0e10cSrcweir 	static sal_Char cDelim1 = (sal_Char)'/';
2542*cdf0e10cSrcweir 	static sal_Char cDelim2 = (sal_Char)'\\';
2543*cdf0e10cSrcweir 	static sal_Char cWild1 = '*';
2544*cdf0e10cSrcweir 	static sal_Char cWild2 = '?';
2545*cdf0e10cSrcweir 
2546*cdf0e10cSrcweir 	delete pRTLData->pWildCard;
2547*cdf0e10cSrcweir 	pRTLData->pWildCard = NULL;
2548*cdf0e10cSrcweir 	pRTLData->sFullNameToBeChecked = String();
2549*cdf0e10cSrcweir 
2550*cdf0e10cSrcweir 	String aFileParam = rFileParam;
2551*cdf0e10cSrcweir 	xub_StrLen nLastWild = aFileParam.SearchBackward( cWild1 );
2552*cdf0e10cSrcweir 	if( nLastWild == STRING_NOTFOUND )
2553*cdf0e10cSrcweir 		nLastWild = aFileParam.SearchBackward( cWild2 );
2554*cdf0e10cSrcweir 	sal_Bool bHasWildcards = ( nLastWild != STRING_NOTFOUND );
2555*cdf0e10cSrcweir 
2556*cdf0e10cSrcweir 
2557*cdf0e10cSrcweir 	xub_StrLen nLastDelim = aFileParam.SearchBackward( cDelim1 );
2558*cdf0e10cSrcweir 	if( nLastDelim == STRING_NOTFOUND )
2559*cdf0e10cSrcweir 		nLastDelim = aFileParam.SearchBackward( cDelim2 );
2560*cdf0e10cSrcweir 
2561*cdf0e10cSrcweir     if( bHasWildcards )
2562*cdf0e10cSrcweir     {
2563*cdf0e10cSrcweir         // Wildcards in path?
2564*cdf0e10cSrcweir         if( nLastDelim != STRING_NOTFOUND && nLastDelim > nLastWild )
2565*cdf0e10cSrcweir             return aFileParam;
2566*cdf0e10cSrcweir     }
2567*cdf0e10cSrcweir     else
2568*cdf0e10cSrcweir     {
2569*cdf0e10cSrcweir 	    String aPathStr = getFullPath( aFileParam );
2570*cdf0e10cSrcweir         if( nLastDelim != aFileParam.Len() - 1 )
2571*cdf0e10cSrcweir             pRTLData->sFullNameToBeChecked = aPathStr;
2572*cdf0e10cSrcweir         return aPathStr;
2573*cdf0e10cSrcweir     }
2574*cdf0e10cSrcweir 
2575*cdf0e10cSrcweir 	String aPureFileName;
2576*cdf0e10cSrcweir 	if( nLastDelim == STRING_NOTFOUND )
2577*cdf0e10cSrcweir 	{
2578*cdf0e10cSrcweir 		aPureFileName = aFileParam;
2579*cdf0e10cSrcweir 		aFileParam = String();
2580*cdf0e10cSrcweir 	}
2581*cdf0e10cSrcweir 	else
2582*cdf0e10cSrcweir 	{
2583*cdf0e10cSrcweir 		aPureFileName = aFileParam.Copy( nLastDelim + 1 );
2584*cdf0e10cSrcweir 		aFileParam = aFileParam.Copy( 0, nLastDelim );
2585*cdf0e10cSrcweir 	}
2586*cdf0e10cSrcweir 
2587*cdf0e10cSrcweir 	// Try again to get a valid URL/UNC-path with only the path
2588*cdf0e10cSrcweir 	String aPathStr = getFullPath( aFileParam );
2589*cdf0e10cSrcweir 	xub_StrLen nPureLen = aPureFileName.Len();
2590*cdf0e10cSrcweir 
2591*cdf0e10cSrcweir 	// Is there a pure file name left? Otherwise the path is
2592*cdf0e10cSrcweir 	// invalid anyway because it was not accepted by OSL before
2593*cdf0e10cSrcweir 	if( nPureLen && aPureFileName != aAsterisk )
2594*cdf0e10cSrcweir 	{
2595*cdf0e10cSrcweir 		pRTLData->pWildCard = new WildCard( aPureFileName );
2596*cdf0e10cSrcweir 	}
2597*cdf0e10cSrcweir 	return aPathStr;
2598*cdf0e10cSrcweir }
2599*cdf0e10cSrcweir 
2600*cdf0e10cSrcweir inline sal_Bool implCheckWildcard( const String& rName, SbiRTLData* pRTLData )
2601*cdf0e10cSrcweir {
2602*cdf0e10cSrcweir 	sal_Bool bMatch = sal_True;
2603*cdf0e10cSrcweir 
2604*cdf0e10cSrcweir 	if( pRTLData->pWildCard )
2605*cdf0e10cSrcweir 		bMatch = pRTLData->pWildCard->Matches( rName );
2606*cdf0e10cSrcweir 	return bMatch;
2607*cdf0e10cSrcweir }
2608*cdf0e10cSrcweir 
2609*cdf0e10cSrcweir 
2610*cdf0e10cSrcweir bool isRootDir( String aDirURLStr )
2611*cdf0e10cSrcweir {
2612*cdf0e10cSrcweir 	INetURLObject aDirURLObj( aDirURLStr );
2613*cdf0e10cSrcweir 	sal_Bool bRoot = sal_False;
2614*cdf0e10cSrcweir 
2615*cdf0e10cSrcweir 	// Check if it's a root directory
2616*cdf0e10cSrcweir 	sal_Int32 nCount = aDirURLObj.getSegmentCount();
2617*cdf0e10cSrcweir 
2618*cdf0e10cSrcweir 	// No segment means Unix root directory "file:///"
2619*cdf0e10cSrcweir 	if( nCount == 0 )
2620*cdf0e10cSrcweir 	{
2621*cdf0e10cSrcweir 		bRoot = sal_True;
2622*cdf0e10cSrcweir 	}
2623*cdf0e10cSrcweir 	// Exactly one segment needs further checking, because it
2624*cdf0e10cSrcweir 	// can be Unix "file:///foo/" -> no root
2625*cdf0e10cSrcweir 	// or Windows  "file:///c:/"  -> root
2626*cdf0e10cSrcweir 	else if( nCount == 1 )
2627*cdf0e10cSrcweir 	{
2628*cdf0e10cSrcweir 		::rtl::OUString aSeg1 = aDirURLObj.getName( 0, sal_True,
2629*cdf0e10cSrcweir 			INetURLObject::DECODE_WITH_CHARSET );
2630*cdf0e10cSrcweir 		if( aSeg1.getStr()[1] == (sal_Unicode)':' )
2631*cdf0e10cSrcweir 		{
2632*cdf0e10cSrcweir 			bRoot = sal_True;
2633*cdf0e10cSrcweir 		}
2634*cdf0e10cSrcweir 	}
2635*cdf0e10cSrcweir 	// More than one segments can never be root
2636*cdf0e10cSrcweir 	// so bRoot remains sal_False
2637*cdf0e10cSrcweir 
2638*cdf0e10cSrcweir     return bRoot;
2639*cdf0e10cSrcweir }
2640*cdf0e10cSrcweir 
2641*cdf0e10cSrcweir RTLFUNC(Dir)
2642*cdf0e10cSrcweir {
2643*cdf0e10cSrcweir     (void)pBasic;
2644*cdf0e10cSrcweir     (void)bWrite;
2645*cdf0e10cSrcweir 
2646*cdf0e10cSrcweir 	String aPath;
2647*cdf0e10cSrcweir 
2648*cdf0e10cSrcweir 	sal_uInt16 nParCount = rPar.Count();
2649*cdf0e10cSrcweir 	if( nParCount > 3 )
2650*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
2651*cdf0e10cSrcweir 	else
2652*cdf0e10cSrcweir 	{
2653*cdf0e10cSrcweir 		SbiRTLData* pRTLData = pINST->GetRTLData();
2654*cdf0e10cSrcweir 
2655*cdf0e10cSrcweir 		// #34645: Kann auch von der URL-Zeile ueber 'macro: Dir' aufgerufen werden
2656*cdf0e10cSrcweir 		// dann existiert kein pRTLData und die Methode muss verlassen werden
2657*cdf0e10cSrcweir 		if( !pRTLData )
2658*cdf0e10cSrcweir 			return;
2659*cdf0e10cSrcweir 
2660*cdf0e10cSrcweir 		// <-- UCB
2661*cdf0e10cSrcweir 		if( hasUno() )
2662*cdf0e10cSrcweir 		{
2663*cdf0e10cSrcweir 			com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess();
2664*cdf0e10cSrcweir 			if( xSFI.is() )
2665*cdf0e10cSrcweir 			{
2666*cdf0e10cSrcweir 				if ( nParCount >= 2 )
2667*cdf0e10cSrcweir 				{
2668*cdf0e10cSrcweir 					String aFileParam = rPar.Get(1)->GetString();
2669*cdf0e10cSrcweir 
2670*cdf0e10cSrcweir 					String aFileURLStr = implSetupWildcard( aFileParam, pRTLData );
2671*cdf0e10cSrcweir                     if( pRTLData->sFullNameToBeChecked.Len() > 0 )
2672*cdf0e10cSrcweir                     {
2673*cdf0e10cSrcweir 						sal_Bool bExists = sal_False;
2674*cdf0e10cSrcweir 						try	{ bExists = xSFI->exists( aFileURLStr ); }
2675*cdf0e10cSrcweir 						catch( Exception & ) {}
2676*cdf0e10cSrcweir 
2677*cdf0e10cSrcweir                         String aNameOnlyStr;
2678*cdf0e10cSrcweir 						if( bExists )
2679*cdf0e10cSrcweir                         {
2680*cdf0e10cSrcweir 							INetURLObject aFileURL( aFileURLStr );
2681*cdf0e10cSrcweir 							aNameOnlyStr = aFileURL.getName( INetURLObject::LAST_SEGMENT,
2682*cdf0e10cSrcweir 								true, INetURLObject::DECODE_WITH_CHARSET );
2683*cdf0e10cSrcweir                         }
2684*cdf0e10cSrcweir 						rPar.Get(0)->PutString( aNameOnlyStr );
2685*cdf0e10cSrcweir 						return;
2686*cdf0e10cSrcweir                     }
2687*cdf0e10cSrcweir 
2688*cdf0e10cSrcweir 					try
2689*cdf0e10cSrcweir 					{
2690*cdf0e10cSrcweir 						String aDirURLStr;
2691*cdf0e10cSrcweir 						sal_Bool bFolder = xSFI->isFolder( aFileURLStr );
2692*cdf0e10cSrcweir 
2693*cdf0e10cSrcweir 						if( bFolder )
2694*cdf0e10cSrcweir 						{
2695*cdf0e10cSrcweir 							aDirURLStr = aFileURLStr;
2696*cdf0e10cSrcweir 						}
2697*cdf0e10cSrcweir 						else
2698*cdf0e10cSrcweir 						{
2699*cdf0e10cSrcweir                             String aEmptyStr;
2700*cdf0e10cSrcweir 							rPar.Get(0)->PutString( aEmptyStr );
2701*cdf0e10cSrcweir 						}
2702*cdf0e10cSrcweir 
2703*cdf0e10cSrcweir 						sal_uInt16 nFlags = 0;
2704*cdf0e10cSrcweir 						if ( nParCount > 2 )
2705*cdf0e10cSrcweir 							pRTLData->nDirFlags = nFlags = rPar.Get(2)->GetInteger();
2706*cdf0e10cSrcweir 						else
2707*cdf0e10cSrcweir 							pRTLData->nDirFlags = 0;
2708*cdf0e10cSrcweir 
2709*cdf0e10cSrcweir 						// Read directory
2710*cdf0e10cSrcweir 						sal_Bool bIncludeFolders = ((nFlags & Sb_ATTR_DIRECTORY) != 0);
2711*cdf0e10cSrcweir 						pRTLData->aDirSeq = xSFI->getFolderContents( aDirURLStr, bIncludeFolders );
2712*cdf0e10cSrcweir 						pRTLData->nCurDirPos = 0;
2713*cdf0e10cSrcweir 
2714*cdf0e10cSrcweir 						// #78651 Add "." and ".." directories for VB compatibility
2715*cdf0e10cSrcweir 						if( bIncludeFolders )
2716*cdf0e10cSrcweir 						{
2717*cdf0e10cSrcweir 							sal_Bool bRoot = isRootDir( aDirURLStr );
2718*cdf0e10cSrcweir 
2719*cdf0e10cSrcweir 							// If it's no root directory we flag the need for
2720*cdf0e10cSrcweir 							// the "." and ".." directories by the value -2
2721*cdf0e10cSrcweir 							// for the actual position. Later for -2 will be
2722*cdf0e10cSrcweir 							// returned "." and for -1 ".."
2723*cdf0e10cSrcweir 							if( !bRoot )
2724*cdf0e10cSrcweir 							{
2725*cdf0e10cSrcweir 								pRTLData->nCurDirPos = -2;
2726*cdf0e10cSrcweir 							}
2727*cdf0e10cSrcweir 						}
2728*cdf0e10cSrcweir 					}
2729*cdf0e10cSrcweir 					catch( Exception & )
2730*cdf0e10cSrcweir 					{
2731*cdf0e10cSrcweir 						//StarBASIC::Error( ERRCODE_IO_GENERAL );
2732*cdf0e10cSrcweir 					}
2733*cdf0e10cSrcweir 				}
2734*cdf0e10cSrcweir 
2735*cdf0e10cSrcweir 
2736*cdf0e10cSrcweir 				if( pRTLData->aDirSeq.getLength() > 0 )
2737*cdf0e10cSrcweir 				{
2738*cdf0e10cSrcweir 					sal_Bool bFolderFlag = ((pRTLData->nDirFlags & Sb_ATTR_DIRECTORY) != 0);
2739*cdf0e10cSrcweir 
2740*cdf0e10cSrcweir 					SbiInstance* pInst = pINST;
2741*cdf0e10cSrcweir 					bool bCompatibility = ( pInst && pInst->IsCompatibility() );
2742*cdf0e10cSrcweir 					for( ;; )
2743*cdf0e10cSrcweir 					{
2744*cdf0e10cSrcweir 						if( pRTLData->nCurDirPos < 0 )
2745*cdf0e10cSrcweir 						{
2746*cdf0e10cSrcweir 							if( pRTLData->nCurDirPos == -2 )
2747*cdf0e10cSrcweir 							{
2748*cdf0e10cSrcweir 								aPath = ::rtl::OUString::createFromAscii( "." );
2749*cdf0e10cSrcweir 							}
2750*cdf0e10cSrcweir 							else if( pRTLData->nCurDirPos == -1 )
2751*cdf0e10cSrcweir 							{
2752*cdf0e10cSrcweir 								aPath = ::rtl::OUString::createFromAscii( ".." );
2753*cdf0e10cSrcweir 							}
2754*cdf0e10cSrcweir 							pRTLData->nCurDirPos++;
2755*cdf0e10cSrcweir 						}
2756*cdf0e10cSrcweir 						else if( pRTLData->nCurDirPos >= pRTLData->aDirSeq.getLength() )
2757*cdf0e10cSrcweir 						{
2758*cdf0e10cSrcweir 							pRTLData->aDirSeq.realloc( 0 );
2759*cdf0e10cSrcweir 							aPath.Erase();
2760*cdf0e10cSrcweir 							break;
2761*cdf0e10cSrcweir 						}
2762*cdf0e10cSrcweir 						else
2763*cdf0e10cSrcweir 						{
2764*cdf0e10cSrcweir 							::rtl::OUString aFile = pRTLData->aDirSeq.getConstArray()[pRTLData->nCurDirPos++];
2765*cdf0e10cSrcweir 
2766*cdf0e10cSrcweir 							if( bCompatibility )
2767*cdf0e10cSrcweir 							{
2768*cdf0e10cSrcweir 								if( !bFolderFlag )
2769*cdf0e10cSrcweir 								{
2770*cdf0e10cSrcweir 									sal_Bool bFolder = xSFI->isFolder( aFile );
2771*cdf0e10cSrcweir 									if( bFolder )
2772*cdf0e10cSrcweir 										continue;
2773*cdf0e10cSrcweir 								}
2774*cdf0e10cSrcweir 							}
2775*cdf0e10cSrcweir 							else
2776*cdf0e10cSrcweir 							{
2777*cdf0e10cSrcweir 								// Only directories
2778*cdf0e10cSrcweir 								if( bFolderFlag )
2779*cdf0e10cSrcweir 								{
2780*cdf0e10cSrcweir 									sal_Bool bFolder = xSFI->isFolder( aFile );
2781*cdf0e10cSrcweir 									if( !bFolder )
2782*cdf0e10cSrcweir 										continue;
2783*cdf0e10cSrcweir 								}
2784*cdf0e10cSrcweir 							}
2785*cdf0e10cSrcweir 
2786*cdf0e10cSrcweir 							INetURLObject aURL( aFile );
2787*cdf0e10cSrcweir 							aPath = aURL.getName( INetURLObject::LAST_SEGMENT, sal_True,
2788*cdf0e10cSrcweir 								INetURLObject::DECODE_WITH_CHARSET );
2789*cdf0e10cSrcweir 						}
2790*cdf0e10cSrcweir 
2791*cdf0e10cSrcweir 						sal_Bool bMatch = implCheckWildcard( aPath, pRTLData );
2792*cdf0e10cSrcweir 						if( !bMatch )
2793*cdf0e10cSrcweir 							continue;
2794*cdf0e10cSrcweir 
2795*cdf0e10cSrcweir 						break;
2796*cdf0e10cSrcweir 					}
2797*cdf0e10cSrcweir 				}
2798*cdf0e10cSrcweir 				rPar.Get(0)->PutString( aPath );
2799*cdf0e10cSrcweir 			}
2800*cdf0e10cSrcweir 		}
2801*cdf0e10cSrcweir 		else
2802*cdf0e10cSrcweir 		// --> UCB
2803*cdf0e10cSrcweir 		{
2804*cdf0e10cSrcweir #ifdef _OLD_FILE_IMPL
2805*cdf0e10cSrcweir 			if ( nParCount >= 2 )
2806*cdf0e10cSrcweir 			{
2807*cdf0e10cSrcweir 				delete pRTLData->pDir;
2808*cdf0e10cSrcweir 				pRTLData->pDir = 0; // wg. Sonderbehandlung Sb_ATTR_VOLUME
2809*cdf0e10cSrcweir 				DirEntry aEntry( rPar.Get(1)->GetString() );
2810*cdf0e10cSrcweir 				FileStat aStat( aEntry );
2811*cdf0e10cSrcweir 				if(!aStat.GetError() && (aStat.GetKind() & FSYS_KIND_FILE))
2812*cdf0e10cSrcweir 				{
2813*cdf0e10cSrcweir 					// ah ja, ist nur ein dateiname
2814*cdf0e10cSrcweir 					// Pfad abschneiden (wg. VB4)
2815*cdf0e10cSrcweir 					rPar.Get(0)->PutString( aEntry.GetName() );
2816*cdf0e10cSrcweir 					return;
2817*cdf0e10cSrcweir 				}
2818*cdf0e10cSrcweir 				sal_uInt16 nFlags = 0;
2819*cdf0e10cSrcweir 				if ( nParCount > 2 )
2820*cdf0e10cSrcweir 					pRTLData->nDirFlags = nFlags = rPar.Get(2)->GetInteger();
2821*cdf0e10cSrcweir 				else
2822*cdf0e10cSrcweir 					pRTLData->nDirFlags = 0;
2823*cdf0e10cSrcweir 
2824*cdf0e10cSrcweir 				// Sb_ATTR_VOLUME wird getrennt gehandelt
2825*cdf0e10cSrcweir 				if( pRTLData->nDirFlags & Sb_ATTR_VOLUME )
2826*cdf0e10cSrcweir 					aPath = aEntry.GetVolume();
2827*cdf0e10cSrcweir 				else
2828*cdf0e10cSrcweir 				{
2829*cdf0e10cSrcweir 					// Die richtige Auswahl treffen
2830*cdf0e10cSrcweir 					sal_uInt16 nMode = FSYS_KIND_FILE;
2831*cdf0e10cSrcweir 					if( nFlags & Sb_ATTR_DIRECTORY )
2832*cdf0e10cSrcweir 						nMode |= FSYS_KIND_DIR;
2833*cdf0e10cSrcweir 					if( nFlags == Sb_ATTR_DIRECTORY )
2834*cdf0e10cSrcweir 						nMode = FSYS_KIND_DIR;
2835*cdf0e10cSrcweir 					pRTLData->pDir = new Dir( aEntry, (DirEntryKind) nMode );
2836*cdf0e10cSrcweir 					pRTLData->nCurDirPos = 0;
2837*cdf0e10cSrcweir 				}
2838*cdf0e10cSrcweir 			}
2839*cdf0e10cSrcweir 
2840*cdf0e10cSrcweir 			if( pRTLData->pDir )
2841*cdf0e10cSrcweir 			{
2842*cdf0e10cSrcweir 				for( ;; )
2843*cdf0e10cSrcweir 				{
2844*cdf0e10cSrcweir 					if( pRTLData->nCurDirPos >= pRTLData->pDir->Count() )
2845*cdf0e10cSrcweir 					{
2846*cdf0e10cSrcweir 						delete pRTLData->pDir;
2847*cdf0e10cSrcweir 						pRTLData->pDir = 0;
2848*cdf0e10cSrcweir 						aPath.Erase();
2849*cdf0e10cSrcweir 						break;
2850*cdf0e10cSrcweir 					}
2851*cdf0e10cSrcweir 					DirEntry aNextEntry=(*(pRTLData->pDir))[pRTLData->nCurDirPos++];
2852*cdf0e10cSrcweir 					aPath = aNextEntry.GetName(); //Full();
2853*cdf0e10cSrcweir 					break;
2854*cdf0e10cSrcweir 				}
2855*cdf0e10cSrcweir 			}
2856*cdf0e10cSrcweir 			rPar.Get(0)->PutString( aPath );
2857*cdf0e10cSrcweir #else
2858*cdf0e10cSrcweir 			// TODO: OSL
2859*cdf0e10cSrcweir 			if ( nParCount >= 2 )
2860*cdf0e10cSrcweir 			{
2861*cdf0e10cSrcweir 				String aFileParam = rPar.Get(1)->GetString();
2862*cdf0e10cSrcweir 
2863*cdf0e10cSrcweir 				String aDirURL = implSetupWildcard( aFileParam, pRTLData );
2864*cdf0e10cSrcweir 
2865*cdf0e10cSrcweir 				sal_uInt16 nFlags = 0;
2866*cdf0e10cSrcweir 				if ( nParCount > 2 )
2867*cdf0e10cSrcweir 					pRTLData->nDirFlags = nFlags = rPar.Get(2)->GetInteger();
2868*cdf0e10cSrcweir 				else
2869*cdf0e10cSrcweir 					pRTLData->nDirFlags = 0;
2870*cdf0e10cSrcweir 
2871*cdf0e10cSrcweir 				// Read directory
2872*cdf0e10cSrcweir 				sal_Bool bIncludeFolders = ((nFlags & Sb_ATTR_DIRECTORY) != 0);
2873*cdf0e10cSrcweir 				pRTLData->pDir = new Directory( aDirURL );
2874*cdf0e10cSrcweir 				FileBase::RC nRet = pRTLData->pDir->open();
2875*cdf0e10cSrcweir 				if( nRet != FileBase::E_None )
2876*cdf0e10cSrcweir 				{
2877*cdf0e10cSrcweir 					delete pRTLData->pDir;
2878*cdf0e10cSrcweir 					pRTLData->pDir = NULL;
2879*cdf0e10cSrcweir 					rPar.Get(0)->PutString( String() );
2880*cdf0e10cSrcweir 					return;
2881*cdf0e10cSrcweir 				}
2882*cdf0e10cSrcweir 
2883*cdf0e10cSrcweir 				// #86950 Add "." and ".." directories for VB compatibility
2884*cdf0e10cSrcweir 				pRTLData->nCurDirPos = 0;
2885*cdf0e10cSrcweir 				if( bIncludeFolders )
2886*cdf0e10cSrcweir 				{
2887*cdf0e10cSrcweir 					sal_Bool bRoot = isRootDir( aDirURL );
2888*cdf0e10cSrcweir 
2889*cdf0e10cSrcweir 					// If it's no root directory we flag the need for
2890*cdf0e10cSrcweir 					// the "." and ".." directories by the value -2
2891*cdf0e10cSrcweir 					// for the actual position. Later for -2 will be
2892*cdf0e10cSrcweir 					// returned "." and for -1 ".."
2893*cdf0e10cSrcweir 					if( !bRoot )
2894*cdf0e10cSrcweir 					{
2895*cdf0e10cSrcweir 						pRTLData->nCurDirPos = -2;
2896*cdf0e10cSrcweir 					}
2897*cdf0e10cSrcweir 				}
2898*cdf0e10cSrcweir 
2899*cdf0e10cSrcweir 			}
2900*cdf0e10cSrcweir 
2901*cdf0e10cSrcweir 			if( pRTLData->pDir )
2902*cdf0e10cSrcweir 			{
2903*cdf0e10cSrcweir 				sal_Bool bFolderFlag = ((pRTLData->nDirFlags & Sb_ATTR_DIRECTORY) != 0);
2904*cdf0e10cSrcweir 				for( ;; )
2905*cdf0e10cSrcweir 				{
2906*cdf0e10cSrcweir 					if( pRTLData->nCurDirPos < 0 )
2907*cdf0e10cSrcweir 					{
2908*cdf0e10cSrcweir 						if( pRTLData->nCurDirPos == -2 )
2909*cdf0e10cSrcweir 						{
2910*cdf0e10cSrcweir 							aPath = ::rtl::OUString::createFromAscii( "." );
2911*cdf0e10cSrcweir 						}
2912*cdf0e10cSrcweir 						else if( pRTLData->nCurDirPos == -1 )
2913*cdf0e10cSrcweir 						{
2914*cdf0e10cSrcweir 							aPath = ::rtl::OUString::createFromAscii( ".." );
2915*cdf0e10cSrcweir 						}
2916*cdf0e10cSrcweir 						pRTLData->nCurDirPos++;
2917*cdf0e10cSrcweir 					}
2918*cdf0e10cSrcweir                     else
2919*cdf0e10cSrcweir                     {
2920*cdf0e10cSrcweir 					    DirectoryItem aItem;
2921*cdf0e10cSrcweir 				        FileBase::RC nRet = pRTLData->pDir->getNextItem( aItem );
2922*cdf0e10cSrcweir 					    if( nRet != FileBase::E_None )
2923*cdf0e10cSrcweir 					    {
2924*cdf0e10cSrcweir 						    delete pRTLData->pDir;
2925*cdf0e10cSrcweir 						    pRTLData->pDir = NULL;
2926*cdf0e10cSrcweir 						    aPath.Erase();
2927*cdf0e10cSrcweir 						    break;
2928*cdf0e10cSrcweir 					    }
2929*cdf0e10cSrcweir 
2930*cdf0e10cSrcweir 					    // Handle flags
2931*cdf0e10cSrcweir 					    FileStatus aFileStatus( FileStatusMask_Type | FileStatusMask_FileName );
2932*cdf0e10cSrcweir 					    nRet = aItem.getFileStatus( aFileStatus );
2933*cdf0e10cSrcweir 
2934*cdf0e10cSrcweir 					    // Only directories?
2935*cdf0e10cSrcweir 					    if( bFolderFlag )
2936*cdf0e10cSrcweir 					    {
2937*cdf0e10cSrcweir 						    FileStatus::Type aType = aFileStatus.getFileType();
2938*cdf0e10cSrcweir 						    sal_Bool bFolder = isFolder( aType );
2939*cdf0e10cSrcweir 						    if( !bFolder )
2940*cdf0e10cSrcweir 							    continue;
2941*cdf0e10cSrcweir 					    }
2942*cdf0e10cSrcweir 
2943*cdf0e10cSrcweir 					    aPath = aFileStatus.getFileName();
2944*cdf0e10cSrcweir                     }
2945*cdf0e10cSrcweir 
2946*cdf0e10cSrcweir 					sal_Bool bMatch = implCheckWildcard( aPath, pRTLData );
2947*cdf0e10cSrcweir 					if( !bMatch )
2948*cdf0e10cSrcweir 						continue;
2949*cdf0e10cSrcweir 
2950*cdf0e10cSrcweir 					break;
2951*cdf0e10cSrcweir 				}
2952*cdf0e10cSrcweir 			}
2953*cdf0e10cSrcweir 			rPar.Get(0)->PutString( aPath );
2954*cdf0e10cSrcweir #endif
2955*cdf0e10cSrcweir 		}
2956*cdf0e10cSrcweir 	}
2957*cdf0e10cSrcweir }
2958*cdf0e10cSrcweir 
2959*cdf0e10cSrcweir 
2960*cdf0e10cSrcweir RTLFUNC(GetAttr)
2961*cdf0e10cSrcweir {
2962*cdf0e10cSrcweir     (void)pBasic;
2963*cdf0e10cSrcweir     (void)bWrite;
2964*cdf0e10cSrcweir 
2965*cdf0e10cSrcweir 	if ( rPar.Count() == 2 )
2966*cdf0e10cSrcweir 	{
2967*cdf0e10cSrcweir 		sal_Int16 nFlags = 0;
2968*cdf0e10cSrcweir 
2969*cdf0e10cSrcweir 		// In Windows, We want to use Windows API to get the file attributes
2970*cdf0e10cSrcweir 		// for VBA interoperability.
2971*cdf0e10cSrcweir 	#if defined( WNT )
2972*cdf0e10cSrcweir 		if( SbiRuntime::isVBAEnabled() )
2973*cdf0e10cSrcweir 		{
2974*cdf0e10cSrcweir 			DirEntry aEntry( rPar.Get(1)->GetString() );
2975*cdf0e10cSrcweir 			aEntry.ToAbs();
2976*cdf0e10cSrcweir 
2977*cdf0e10cSrcweir 			// #57064 Bei virtuellen URLs den Real-Path extrahieren
2978*cdf0e10cSrcweir 			ByteString aByteStrFullPath( aEntry.GetFull(), gsl_getSystemTextEncoding() );
2979*cdf0e10cSrcweir 			DWORD nRealFlags = GetFileAttributes (aByteStrFullPath.GetBuffer());
2980*cdf0e10cSrcweir 			if (nRealFlags != 0xffffffff)
2981*cdf0e10cSrcweir 			{
2982*cdf0e10cSrcweir 				if (nRealFlags == FILE_ATTRIBUTE_NORMAL)
2983*cdf0e10cSrcweir 					nRealFlags = 0;
2984*cdf0e10cSrcweir 				nFlags = (sal_Int16) (nRealFlags);
2985*cdf0e10cSrcweir 			}
2986*cdf0e10cSrcweir 			else
2987*cdf0e10cSrcweir 				StarBASIC::Error( SbERR_FILE_NOT_FOUND );
2988*cdf0e10cSrcweir 
2989*cdf0e10cSrcweir 			rPar.Get(0)->PutInteger( nFlags );
2990*cdf0e10cSrcweir 
2991*cdf0e10cSrcweir 			return;
2992*cdf0e10cSrcweir 		}
2993*cdf0e10cSrcweir 	#endif
2994*cdf0e10cSrcweir 
2995*cdf0e10cSrcweir 		// <-- UCB
2996*cdf0e10cSrcweir 		if( hasUno() )
2997*cdf0e10cSrcweir 		{
2998*cdf0e10cSrcweir 			com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess();
2999*cdf0e10cSrcweir 			if( xSFI.is() )
3000*cdf0e10cSrcweir 			{
3001*cdf0e10cSrcweir 				try
3002*cdf0e10cSrcweir 				{
3003*cdf0e10cSrcweir 					String aPath = getFullPath( rPar.Get(1)->GetString() );
3004*cdf0e10cSrcweir 					sal_Bool bExists = sal_False;
3005*cdf0e10cSrcweir 					try { bExists = xSFI->exists( aPath ); }
3006*cdf0e10cSrcweir 					catch( Exception & ) {}
3007*cdf0e10cSrcweir 					if( !bExists )
3008*cdf0e10cSrcweir 					{
3009*cdf0e10cSrcweir 						StarBASIC::Error( SbERR_FILE_NOT_FOUND );
3010*cdf0e10cSrcweir 						return;
3011*cdf0e10cSrcweir 					}
3012*cdf0e10cSrcweir 
3013*cdf0e10cSrcweir 					sal_Bool bReadOnly = xSFI->isReadOnly( aPath );
3014*cdf0e10cSrcweir 					sal_Bool bHidden = xSFI->isHidden( aPath );
3015*cdf0e10cSrcweir 					sal_Bool bDirectory = xSFI->isFolder( aPath );
3016*cdf0e10cSrcweir 					if( bReadOnly )
3017*cdf0e10cSrcweir 						nFlags |= 0x0001; // ATTR_READONLY
3018*cdf0e10cSrcweir 					if( bHidden )
3019*cdf0e10cSrcweir 						nFlags |= 0x0002; // ATTR_HIDDEN
3020*cdf0e10cSrcweir 					if( bDirectory )
3021*cdf0e10cSrcweir 						nFlags |= 0x0010; // ATTR_DIRECTORY
3022*cdf0e10cSrcweir 				}
3023*cdf0e10cSrcweir 				catch( Exception & )
3024*cdf0e10cSrcweir 				{
3025*cdf0e10cSrcweir 					StarBASIC::Error( ERRCODE_IO_GENERAL );
3026*cdf0e10cSrcweir 				}
3027*cdf0e10cSrcweir 			}
3028*cdf0e10cSrcweir 		}
3029*cdf0e10cSrcweir 		else
3030*cdf0e10cSrcweir 		// --> UCB
3031*cdf0e10cSrcweir 		{
3032*cdf0e10cSrcweir 			DirectoryItem aItem;
3033*cdf0e10cSrcweir 			FileBase::RC nRet = DirectoryItem::get( getFullPathUNC( rPar.Get(1)->GetString() ), aItem );
3034*cdf0e10cSrcweir 			FileStatus aFileStatus( FileStatusMask_Attributes | FileStatusMask_Type );
3035*cdf0e10cSrcweir 			nRet = aItem.getFileStatus( aFileStatus );
3036*cdf0e10cSrcweir 			sal_uInt64 nAttributes = aFileStatus.getAttributes();
3037*cdf0e10cSrcweir 			sal_Bool bReadOnly = (nAttributes & Attribute_ReadOnly) != 0;
3038*cdf0e10cSrcweir 
3039*cdf0e10cSrcweir 			FileStatus::Type aType = aFileStatus.getFileType();
3040*cdf0e10cSrcweir 			sal_Bool bDirectory = isFolder( aType );
3041*cdf0e10cSrcweir 			if( bReadOnly )
3042*cdf0e10cSrcweir 				nFlags |= 0x0001; // ATTR_READONLY
3043*cdf0e10cSrcweir 			if( bDirectory )
3044*cdf0e10cSrcweir 				nFlags |= 0x0010; // ATTR_DIRECTORY
3045*cdf0e10cSrcweir 		}
3046*cdf0e10cSrcweir 		rPar.Get(0)->PutInteger( nFlags );
3047*cdf0e10cSrcweir 	}
3048*cdf0e10cSrcweir 	else
3049*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
3050*cdf0e10cSrcweir }
3051*cdf0e10cSrcweir 
3052*cdf0e10cSrcweir 
3053*cdf0e10cSrcweir RTLFUNC(FileDateTime)
3054*cdf0e10cSrcweir {
3055*cdf0e10cSrcweir     (void)pBasic;
3056*cdf0e10cSrcweir     (void)bWrite;
3057*cdf0e10cSrcweir 
3058*cdf0e10cSrcweir 	if ( rPar.Count() != 2 )
3059*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
3060*cdf0e10cSrcweir 	else
3061*cdf0e10cSrcweir 	{
3062*cdf0e10cSrcweir 		// <-- UCB
3063*cdf0e10cSrcweir 		String aPath = rPar.Get(1)->GetString();
3064*cdf0e10cSrcweir 		Time aTime;
3065*cdf0e10cSrcweir 		Date aDate;
3066*cdf0e10cSrcweir 		if( hasUno() )
3067*cdf0e10cSrcweir 		{
3068*cdf0e10cSrcweir 			com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess();
3069*cdf0e10cSrcweir 			if( xSFI.is() )
3070*cdf0e10cSrcweir 			{
3071*cdf0e10cSrcweir 				try
3072*cdf0e10cSrcweir 				{
3073*cdf0e10cSrcweir 					com::sun::star::util::DateTime aUnoDT = xSFI->getDateTimeModified( aPath );
3074*cdf0e10cSrcweir 					aTime = Time( aUnoDT.Hours, aUnoDT.Minutes, aUnoDT.Seconds, aUnoDT.HundredthSeconds );
3075*cdf0e10cSrcweir 					aDate = Date( aUnoDT.Day, aUnoDT.Month, aUnoDT.Year );
3076*cdf0e10cSrcweir 				}
3077*cdf0e10cSrcweir 				catch( Exception & )
3078*cdf0e10cSrcweir 				{
3079*cdf0e10cSrcweir 					StarBASIC::Error( ERRCODE_IO_GENERAL );
3080*cdf0e10cSrcweir 				}
3081*cdf0e10cSrcweir 			}
3082*cdf0e10cSrcweir 		}
3083*cdf0e10cSrcweir 		else
3084*cdf0e10cSrcweir 		// --> UCB
3085*cdf0e10cSrcweir 		{
3086*cdf0e10cSrcweir #ifdef _OLD_FILE_IMPL
3087*cdf0e10cSrcweir 			DirEntry aEntry( aPath );
3088*cdf0e10cSrcweir 			FileStat aStat( aEntry );
3089*cdf0e10cSrcweir 			aTime = Time( aStat.TimeModified() );
3090*cdf0e10cSrcweir 			aDate = Date( aStat.DateModified() );
3091*cdf0e10cSrcweir #else
3092*cdf0e10cSrcweir 			DirectoryItem aItem;
3093*cdf0e10cSrcweir 			FileBase::RC nRet = DirectoryItem::get( getFullPathUNC( aPath ), aItem );
3094*cdf0e10cSrcweir 			FileStatus aFileStatus( FileStatusMask_ModifyTime );
3095*cdf0e10cSrcweir 		    nRet = aItem.getFileStatus( aFileStatus );
3096*cdf0e10cSrcweir 		    TimeValue aTimeVal = aFileStatus.getModifyTime();
3097*cdf0e10cSrcweir 			oslDateTime aDT;
3098*cdf0e10cSrcweir 			osl_getDateTimeFromTimeValue( &aTimeVal, &aDT );
3099*cdf0e10cSrcweir 
3100*cdf0e10cSrcweir 			aTime = Time( aDT.Hours, aDT.Minutes, aDT.Seconds, 10000000*aDT.NanoSeconds );
3101*cdf0e10cSrcweir 			aDate = Date( aDT.Day, aDT.Month, aDT.Year );
3102*cdf0e10cSrcweir #endif
3103*cdf0e10cSrcweir 		}
3104*cdf0e10cSrcweir 
3105*cdf0e10cSrcweir 		double fSerial = (double)GetDayDiff( aDate );
3106*cdf0e10cSrcweir 		long nSeconds = aTime.GetHour();
3107*cdf0e10cSrcweir 		nSeconds *= 3600;
3108*cdf0e10cSrcweir 		nSeconds += aTime.GetMin() * 60;
3109*cdf0e10cSrcweir 		nSeconds += aTime.GetSec();
3110*cdf0e10cSrcweir 		double nDays = ((double)nSeconds) / (double)(24.0*3600.0);
3111*cdf0e10cSrcweir 		fSerial += nDays;
3112*cdf0e10cSrcweir 
3113*cdf0e10cSrcweir 		Color* pCol;
3114*cdf0e10cSrcweir 
3115*cdf0e10cSrcweir 		// #39629 pINST pruefen, kann aus URL-Zeile gerufen werden
3116*cdf0e10cSrcweir 		SvNumberFormatter* pFormatter = NULL;
3117*cdf0e10cSrcweir 		sal_uInt32 nIndex;
3118*cdf0e10cSrcweir 		if( pINST )
3119*cdf0e10cSrcweir 		{
3120*cdf0e10cSrcweir 			pFormatter = pINST->GetNumberFormatter();
3121*cdf0e10cSrcweir 			nIndex = pINST->GetStdDateTimeIdx();
3122*cdf0e10cSrcweir 		}
3123*cdf0e10cSrcweir 		else
3124*cdf0e10cSrcweir 		{
3125*cdf0e10cSrcweir 			sal_uInt32 n;	// Dummy
3126*cdf0e10cSrcweir 			SbiInstance::PrepareNumberFormatter( pFormatter, n, n, nIndex );
3127*cdf0e10cSrcweir 		}
3128*cdf0e10cSrcweir 
3129*cdf0e10cSrcweir 		String aRes;
3130*cdf0e10cSrcweir 		pFormatter->GetOutputString( fSerial, nIndex, aRes, &pCol );
3131*cdf0e10cSrcweir 		rPar.Get(0)->PutString( aRes );
3132*cdf0e10cSrcweir 
3133*cdf0e10cSrcweir 		// #39629 pFormatter kann selbst angefordert sein
3134*cdf0e10cSrcweir 		if( !pINST )
3135*cdf0e10cSrcweir 			delete pFormatter;
3136*cdf0e10cSrcweir 	}
3137*cdf0e10cSrcweir }
3138*cdf0e10cSrcweir 
3139*cdf0e10cSrcweir 
3140*cdf0e10cSrcweir RTLFUNC(EOF)
3141*cdf0e10cSrcweir {
3142*cdf0e10cSrcweir     (void)pBasic;
3143*cdf0e10cSrcweir     (void)bWrite;
3144*cdf0e10cSrcweir 
3145*cdf0e10cSrcweir 	// AB 08/16/2000: No changes for UCB
3146*cdf0e10cSrcweir 	if ( rPar.Count() != 2 )
3147*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
3148*cdf0e10cSrcweir 	else
3149*cdf0e10cSrcweir 	{
3150*cdf0e10cSrcweir 		sal_Int16 nChannel = rPar.Get(1)->GetInteger();
3151*cdf0e10cSrcweir 		// nChannel--;  // macht MD beim Oeffnen auch nicht
3152*cdf0e10cSrcweir 		SbiIoSystem* pIO = pINST->GetIoSystem();
3153*cdf0e10cSrcweir 		SbiStream* pSbStrm = pIO->GetStream( nChannel );
3154*cdf0e10cSrcweir 		if ( !pSbStrm )
3155*cdf0e10cSrcweir 		{
3156*cdf0e10cSrcweir 			StarBASIC::Error( SbERR_BAD_CHANNEL );
3157*cdf0e10cSrcweir 			return;
3158*cdf0e10cSrcweir 		}
3159*cdf0e10cSrcweir 		sal_Bool bIsEof;
3160*cdf0e10cSrcweir 		SvStream* pSvStrm = pSbStrm->GetStrm();
3161*cdf0e10cSrcweir 		if ( pSbStrm->IsText() )
3162*cdf0e10cSrcweir 		{
3163*cdf0e10cSrcweir 			char cBla;
3164*cdf0e10cSrcweir 			(*pSvStrm) >> cBla;	// koennen wir noch ein Zeichen lesen
3165*cdf0e10cSrcweir 			bIsEof = pSvStrm->IsEof();
3166*cdf0e10cSrcweir 			if ( !bIsEof )
3167*cdf0e10cSrcweir 				pSvStrm->SeekRel( -1 );
3168*cdf0e10cSrcweir 		}
3169*cdf0e10cSrcweir 		else
3170*cdf0e10cSrcweir 			bIsEof = pSvStrm->IsEof();  // fuer binaerdateien!
3171*cdf0e10cSrcweir 		rPar.Get(0)->PutBool( bIsEof );
3172*cdf0e10cSrcweir 	}
3173*cdf0e10cSrcweir }
3174*cdf0e10cSrcweir 
3175*cdf0e10cSrcweir RTLFUNC(FileAttr)
3176*cdf0e10cSrcweir {
3177*cdf0e10cSrcweir     (void)pBasic;
3178*cdf0e10cSrcweir     (void)bWrite;
3179*cdf0e10cSrcweir 
3180*cdf0e10cSrcweir 	// AB 08/16/2000: No changes for UCB
3181*cdf0e10cSrcweir 
3182*cdf0e10cSrcweir 	// #57064 Obwohl diese Funktion nicht mit DirEntry arbeitet, ist sie von
3183*cdf0e10cSrcweir 	// der Anpassung an virtuelle URLs nich betroffen, da sie nur auf bereits
3184*cdf0e10cSrcweir 	// geoeffneten Dateien arbeitet und der Name hier keine Rolle spielt.
3185*cdf0e10cSrcweir 
3186*cdf0e10cSrcweir 	if ( rPar.Count() != 3 )
3187*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
3188*cdf0e10cSrcweir 	else
3189*cdf0e10cSrcweir 	{
3190*cdf0e10cSrcweir 		sal_Int16 nChannel = rPar.Get(1)->GetInteger();
3191*cdf0e10cSrcweir //		nChannel--;
3192*cdf0e10cSrcweir 		SbiIoSystem* pIO = pINST->GetIoSystem();
3193*cdf0e10cSrcweir 		SbiStream* pSbStrm = pIO->GetStream( nChannel );
3194*cdf0e10cSrcweir 		if ( !pSbStrm )
3195*cdf0e10cSrcweir 		{
3196*cdf0e10cSrcweir 			StarBASIC::Error( SbERR_BAD_CHANNEL );
3197*cdf0e10cSrcweir 			return;
3198*cdf0e10cSrcweir 		}
3199*cdf0e10cSrcweir 		sal_Int16 nRet;
3200*cdf0e10cSrcweir 		if ( rPar.Get(2)->GetInteger() == 1 )
3201*cdf0e10cSrcweir 			nRet = (sal_Int16)(pSbStrm->GetMode());
3202*cdf0e10cSrcweir 		else
3203*cdf0e10cSrcweir 			nRet = 0; // System file handle not supported
3204*cdf0e10cSrcweir 
3205*cdf0e10cSrcweir 		rPar.Get(0)->PutInteger( nRet );
3206*cdf0e10cSrcweir 	}
3207*cdf0e10cSrcweir }
3208*cdf0e10cSrcweir RTLFUNC(Loc)
3209*cdf0e10cSrcweir {
3210*cdf0e10cSrcweir     (void)pBasic;
3211*cdf0e10cSrcweir     (void)bWrite;
3212*cdf0e10cSrcweir 
3213*cdf0e10cSrcweir 	// AB 08/16/2000: No changes for UCB
3214*cdf0e10cSrcweir 	if ( rPar.Count() != 2 )
3215*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
3216*cdf0e10cSrcweir 	else
3217*cdf0e10cSrcweir 	{
3218*cdf0e10cSrcweir 		sal_Int16 nChannel = rPar.Get(1)->GetInteger();
3219*cdf0e10cSrcweir 		SbiIoSystem* pIO = pINST->GetIoSystem();
3220*cdf0e10cSrcweir 		SbiStream* pSbStrm = pIO->GetStream( nChannel );
3221*cdf0e10cSrcweir 		if ( !pSbStrm )
3222*cdf0e10cSrcweir 		{
3223*cdf0e10cSrcweir 			StarBASIC::Error( SbERR_BAD_CHANNEL );
3224*cdf0e10cSrcweir 			return;
3225*cdf0e10cSrcweir 		}
3226*cdf0e10cSrcweir 		SvStream* pSvStrm = pSbStrm->GetStrm();
3227*cdf0e10cSrcweir 		sal_uIntPtr nPos;
3228*cdf0e10cSrcweir 		if( pSbStrm->IsRandom())
3229*cdf0e10cSrcweir 		{
3230*cdf0e10cSrcweir 			short nBlockLen = pSbStrm->GetBlockLen();
3231*cdf0e10cSrcweir 			nPos = nBlockLen ? (pSvStrm->Tell() / nBlockLen) : 0;
3232*cdf0e10cSrcweir 			nPos++; // Blockpositionen beginnen bei 1
3233*cdf0e10cSrcweir 		}
3234*cdf0e10cSrcweir 		else if ( pSbStrm->IsText() )
3235*cdf0e10cSrcweir 			nPos = pSbStrm->GetLine();
3236*cdf0e10cSrcweir 		else if( pSbStrm->IsBinary() )
3237*cdf0e10cSrcweir 			nPos = pSvStrm->Tell();
3238*cdf0e10cSrcweir 		else if ( pSbStrm->IsSeq() )
3239*cdf0e10cSrcweir 			nPos = ( pSvStrm->Tell()+1 ) / 128;
3240*cdf0e10cSrcweir 		else
3241*cdf0e10cSrcweir 			nPos = pSvStrm->Tell();
3242*cdf0e10cSrcweir 		rPar.Get(0)->PutLong( (sal_Int32)nPos );
3243*cdf0e10cSrcweir 	}
3244*cdf0e10cSrcweir }
3245*cdf0e10cSrcweir 
3246*cdf0e10cSrcweir RTLFUNC(Lof)
3247*cdf0e10cSrcweir {
3248*cdf0e10cSrcweir     (void)pBasic;
3249*cdf0e10cSrcweir     (void)bWrite;
3250*cdf0e10cSrcweir 
3251*cdf0e10cSrcweir 	// AB 08/16/2000: No changes for UCB
3252*cdf0e10cSrcweir 	if ( rPar.Count() != 2 )
3253*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
3254*cdf0e10cSrcweir 	else
3255*cdf0e10cSrcweir 	{
3256*cdf0e10cSrcweir 		sal_Int16 nChannel = rPar.Get(1)->GetInteger();
3257*cdf0e10cSrcweir 		SbiIoSystem* pIO = pINST->GetIoSystem();
3258*cdf0e10cSrcweir 		SbiStream* pSbStrm = pIO->GetStream( nChannel );
3259*cdf0e10cSrcweir 		if ( !pSbStrm )
3260*cdf0e10cSrcweir 		{
3261*cdf0e10cSrcweir 			StarBASIC::Error( SbERR_BAD_CHANNEL );
3262*cdf0e10cSrcweir 			return;
3263*cdf0e10cSrcweir 		}
3264*cdf0e10cSrcweir 		SvStream* pSvStrm = pSbStrm->GetStrm();
3265*cdf0e10cSrcweir 		sal_uIntPtr nOldPos = pSvStrm->Tell();
3266*cdf0e10cSrcweir 		sal_uIntPtr nLen = pSvStrm->Seek( STREAM_SEEK_TO_END );
3267*cdf0e10cSrcweir 		pSvStrm->Seek( nOldPos );
3268*cdf0e10cSrcweir 		rPar.Get(0)->PutLong( (sal_Int32)nLen );
3269*cdf0e10cSrcweir 	}
3270*cdf0e10cSrcweir }
3271*cdf0e10cSrcweir 
3272*cdf0e10cSrcweir 
3273*cdf0e10cSrcweir RTLFUNC(Seek)
3274*cdf0e10cSrcweir {
3275*cdf0e10cSrcweir     (void)pBasic;
3276*cdf0e10cSrcweir     (void)bWrite;
3277*cdf0e10cSrcweir 
3278*cdf0e10cSrcweir 	// AB 08/16/2000: No changes for UCB
3279*cdf0e10cSrcweir 	int nArgs = (int)rPar.Count();
3280*cdf0e10cSrcweir 	if ( nArgs < 2 || nArgs > 3 )
3281*cdf0e10cSrcweir 	{
3282*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
3283*cdf0e10cSrcweir 		return;
3284*cdf0e10cSrcweir 	}
3285*cdf0e10cSrcweir 	sal_Int16 nChannel = rPar.Get(1)->GetInteger();
3286*cdf0e10cSrcweir //	nChannel--;
3287*cdf0e10cSrcweir 	SbiIoSystem* pIO = pINST->GetIoSystem();
3288*cdf0e10cSrcweir 	SbiStream* pSbStrm = pIO->GetStream( nChannel );
3289*cdf0e10cSrcweir 	if ( !pSbStrm )
3290*cdf0e10cSrcweir 	{
3291*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_CHANNEL );
3292*cdf0e10cSrcweir 		return;
3293*cdf0e10cSrcweir 	}
3294*cdf0e10cSrcweir 	SvStream* pStrm = pSbStrm->GetStrm();
3295*cdf0e10cSrcweir 
3296*cdf0e10cSrcweir 	if ( nArgs == 2 )   // Seek-Function
3297*cdf0e10cSrcweir 	{
3298*cdf0e10cSrcweir 		sal_uIntPtr nPos = pStrm->Tell();
3299*cdf0e10cSrcweir 		if( pSbStrm->IsRandom() )
3300*cdf0e10cSrcweir 			nPos = nPos / pSbStrm->GetBlockLen();
3301*cdf0e10cSrcweir 		nPos++;	// Basic zaehlt ab 1
3302*cdf0e10cSrcweir 		rPar.Get(0)->PutLong( (sal_Int32)nPos );
3303*cdf0e10cSrcweir 	}
3304*cdf0e10cSrcweir 	else                // Seek-Statement
3305*cdf0e10cSrcweir 	{
3306*cdf0e10cSrcweir 		sal_Int32 nPos = rPar.Get(2)->GetLong();
3307*cdf0e10cSrcweir 		if ( nPos < 1 )
3308*cdf0e10cSrcweir 		{
3309*cdf0e10cSrcweir 			StarBASIC::Error( SbERR_BAD_ARGUMENT );
3310*cdf0e10cSrcweir 			return;
3311*cdf0e10cSrcweir 		}
3312*cdf0e10cSrcweir 		nPos--; // Basic zaehlt ab 1, SvStreams zaehlen ab 0
3313*cdf0e10cSrcweir 		pSbStrm->SetExpandOnWriteTo( 0 );
3314*cdf0e10cSrcweir 		if ( pSbStrm->IsRandom() )
3315*cdf0e10cSrcweir 			nPos *= pSbStrm->GetBlockLen();
3316*cdf0e10cSrcweir 		pStrm->Seek( (sal_uIntPtr)nPos );
3317*cdf0e10cSrcweir 		pSbStrm->SetExpandOnWriteTo( nPos );
3318*cdf0e10cSrcweir 	}
3319*cdf0e10cSrcweir }
3320*cdf0e10cSrcweir 
3321*cdf0e10cSrcweir RTLFUNC(Format)
3322*cdf0e10cSrcweir {
3323*cdf0e10cSrcweir     (void)pBasic;
3324*cdf0e10cSrcweir     (void)bWrite;
3325*cdf0e10cSrcweir 
3326*cdf0e10cSrcweir 	sal_uInt16 nArgCount = (sal_uInt16)rPar.Count();
3327*cdf0e10cSrcweir 	if ( nArgCount < 2 || nArgCount > 3 )
3328*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
3329*cdf0e10cSrcweir 	else
3330*cdf0e10cSrcweir 	{
3331*cdf0e10cSrcweir 		String aResult;
3332*cdf0e10cSrcweir 		if( nArgCount == 2 )
3333*cdf0e10cSrcweir 			rPar.Get(1)->Format( aResult );
3334*cdf0e10cSrcweir 		else
3335*cdf0e10cSrcweir 		{
3336*cdf0e10cSrcweir 			String aFmt( rPar.Get(2)->GetString() );
3337*cdf0e10cSrcweir 		    rPar.Get(1)->Format( aResult, &aFmt );
3338*cdf0e10cSrcweir 		}
3339*cdf0e10cSrcweir 		rPar.Get(0)->PutString( aResult );
3340*cdf0e10cSrcweir 	}
3341*cdf0e10cSrcweir }
3342*cdf0e10cSrcweir 
3343*cdf0e10cSrcweir RTLFUNC(Randomize)
3344*cdf0e10cSrcweir {
3345*cdf0e10cSrcweir     (void)pBasic;
3346*cdf0e10cSrcweir     (void)bWrite;
3347*cdf0e10cSrcweir 
3348*cdf0e10cSrcweir 	if ( rPar.Count() > 2 )
3349*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
3350*cdf0e10cSrcweir 	sal_Int16 nSeed;
3351*cdf0e10cSrcweir 	if( rPar.Count() == 2 )
3352*cdf0e10cSrcweir 		nSeed = (sal_Int16)rPar.Get(1)->GetInteger();
3353*cdf0e10cSrcweir 	else
3354*cdf0e10cSrcweir 		nSeed = (sal_Int16)rand();
3355*cdf0e10cSrcweir 	srand( nSeed );
3356*cdf0e10cSrcweir }
3357*cdf0e10cSrcweir 
3358*cdf0e10cSrcweir RTLFUNC(Rnd)
3359*cdf0e10cSrcweir {
3360*cdf0e10cSrcweir     (void)pBasic;
3361*cdf0e10cSrcweir     (void)bWrite;
3362*cdf0e10cSrcweir 
3363*cdf0e10cSrcweir 	if ( rPar.Count() > 2 )
3364*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
3365*cdf0e10cSrcweir 	else
3366*cdf0e10cSrcweir 	{
3367*cdf0e10cSrcweir 		double nRand = (double)rand();
3368*cdf0e10cSrcweir 		nRand = ( nRand / (double)RAND_MAX );
3369*cdf0e10cSrcweir 		rPar.Get(0)->PutDouble( nRand );
3370*cdf0e10cSrcweir 	}
3371*cdf0e10cSrcweir }
3372*cdf0e10cSrcweir 
3373*cdf0e10cSrcweir 
3374*cdf0e10cSrcweir //
3375*cdf0e10cSrcweir //  Syntax: Shell("Path",[ Window-Style,[ "Params", [ bSync = sal_False ]]])
3376*cdf0e10cSrcweir //
3377*cdf0e10cSrcweir //  WindowStyles (VBA-kompatibel):
3378*cdf0e10cSrcweir //      2 == Minimized
3379*cdf0e10cSrcweir //	    3 == Maximized
3380*cdf0e10cSrcweir //     10 == Full-Screen (Textmodus-Anwendungen OS/2, WIN95, WNT)
3381*cdf0e10cSrcweir //
3382*cdf0e10cSrcweir // !!!HACK der WindowStyle wird im Creator an Application::StartApp
3383*cdf0e10cSrcweir //         uebergeben. Format: "xxxx2"
3384*cdf0e10cSrcweir //
3385*cdf0e10cSrcweir 
3386*cdf0e10cSrcweir 
3387*cdf0e10cSrcweir RTLFUNC(Shell)
3388*cdf0e10cSrcweir {
3389*cdf0e10cSrcweir     (void)pBasic;
3390*cdf0e10cSrcweir     (void)bWrite;
3391*cdf0e10cSrcweir 
3392*cdf0e10cSrcweir 	// No shell command for "virtual" portal users
3393*cdf0e10cSrcweir 	if( needSecurityRestrictions() )
3394*cdf0e10cSrcweir 	{
3395*cdf0e10cSrcweir 		StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
3396*cdf0e10cSrcweir 		return;
3397*cdf0e10cSrcweir 	}
3398*cdf0e10cSrcweir 
3399*cdf0e10cSrcweir 	sal_uIntPtr nArgCount = rPar.Count();
3400*cdf0e10cSrcweir 	if ( nArgCount < 2 || nArgCount > 5 )
3401*cdf0e10cSrcweir 	{
3402*cdf0e10cSrcweir 		rPar.Get(0)->PutLong(0);
3403*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
3404*cdf0e10cSrcweir 	}
3405*cdf0e10cSrcweir 	else
3406*cdf0e10cSrcweir 	{
3407*cdf0e10cSrcweir 		sal_uInt16 nOptions = vos::OProcess::TOption_SearchPath|
3408*cdf0e10cSrcweir 						  vos::OProcess::TOption_Detached;
3409*cdf0e10cSrcweir 		String aCmdLine = rPar.Get(1)->GetString();
3410*cdf0e10cSrcweir 		// Zusaetzliche Parameter anhaengen, es muss eh alles geparsed werden
3411*cdf0e10cSrcweir 		if( nArgCount >= 4 )
3412*cdf0e10cSrcweir 		{
3413*cdf0e10cSrcweir 			aCmdLine.AppendAscii( " " );
3414*cdf0e10cSrcweir 			aCmdLine += rPar.Get(3)->GetString();
3415*cdf0e10cSrcweir 		}
3416*cdf0e10cSrcweir 		else if( !aCmdLine.Len() )
3417*cdf0e10cSrcweir 		{
3418*cdf0e10cSrcweir 			// Spezial-Behandlung (leere Liste) vermeiden
3419*cdf0e10cSrcweir 			aCmdLine.AppendAscii( " " );
3420*cdf0e10cSrcweir 		}
3421*cdf0e10cSrcweir 		sal_uInt16 nLen = aCmdLine.Len();
3422*cdf0e10cSrcweir 
3423*cdf0e10cSrcweir 		// #55735 Wenn Parameter dabei sind, muessen die abgetrennt werden
3424*cdf0e10cSrcweir 		// #72471 Auch die einzelnen Parameter trennen
3425*cdf0e10cSrcweir 		std::list<String> aTokenList;
3426*cdf0e10cSrcweir 		String aToken;
3427*cdf0e10cSrcweir 		sal_uInt16 i = 0;
3428*cdf0e10cSrcweir 		sal_Unicode c;
3429*cdf0e10cSrcweir 		while( i < nLen )
3430*cdf0e10cSrcweir 		{
3431*cdf0e10cSrcweir 			// Spaces weg
3432*cdf0e10cSrcweir             for ( ;; ++i )
3433*cdf0e10cSrcweir             {
3434*cdf0e10cSrcweir                 c = aCmdLine.GetBuffer()[ i ];
3435*cdf0e10cSrcweir                 if ( c != ' ' && c != '\t' )
3436*cdf0e10cSrcweir                     break;
3437*cdf0e10cSrcweir             }
3438*cdf0e10cSrcweir 
3439*cdf0e10cSrcweir 			if( c == '\"' || c == '\'' )
3440*cdf0e10cSrcweir 			{
3441*cdf0e10cSrcweir 				sal_uInt16 iFoundPos = aCmdLine.Search( c, i + 1 );
3442*cdf0e10cSrcweir 
3443*cdf0e10cSrcweir 				// Wenn nichts gefunden wurde, Rest kopieren
3444*cdf0e10cSrcweir 				if( iFoundPos == STRING_NOTFOUND )
3445*cdf0e10cSrcweir 				{
3446*cdf0e10cSrcweir 					aToken = aCmdLine.Copy( i, STRING_LEN );
3447*cdf0e10cSrcweir 					i = nLen;
3448*cdf0e10cSrcweir 				}
3449*cdf0e10cSrcweir 				else
3450*cdf0e10cSrcweir 				{
3451*cdf0e10cSrcweir 					aToken = aCmdLine.Copy( i + 1, (iFoundPos - i - 1) );
3452*cdf0e10cSrcweir 					i = iFoundPos + 1;
3453*cdf0e10cSrcweir 				}
3454*cdf0e10cSrcweir 			}
3455*cdf0e10cSrcweir 			else
3456*cdf0e10cSrcweir 			{
3457*cdf0e10cSrcweir 				sal_uInt16 iFoundSpacePos = aCmdLine.Search( ' ', i );
3458*cdf0e10cSrcweir 				sal_uInt16 iFoundTabPos = aCmdLine.Search( '\t', i );
3459*cdf0e10cSrcweir 				sal_uInt16 iFoundPos = Min( iFoundSpacePos, iFoundTabPos );
3460*cdf0e10cSrcweir 
3461*cdf0e10cSrcweir 				// Wenn nichts gefunden wurde, Rest kopieren
3462*cdf0e10cSrcweir 				if( iFoundPos == STRING_NOTFOUND )
3463*cdf0e10cSrcweir 				{
3464*cdf0e10cSrcweir 					aToken = aCmdLine.Copy( i, STRING_LEN );
3465*cdf0e10cSrcweir 					i = nLen;
3466*cdf0e10cSrcweir 				}
3467*cdf0e10cSrcweir 				else
3468*cdf0e10cSrcweir 				{
3469*cdf0e10cSrcweir 					aToken = aCmdLine.Copy( i, (iFoundPos - i) );
3470*cdf0e10cSrcweir 					i = iFoundPos;
3471*cdf0e10cSrcweir 				}
3472*cdf0e10cSrcweir 			}
3473*cdf0e10cSrcweir 
3474*cdf0e10cSrcweir 			// In die Liste uebernehmen
3475*cdf0e10cSrcweir 			aTokenList.push_back( aToken );
3476*cdf0e10cSrcweir 		}
3477*cdf0e10cSrcweir 		// #55735 / #72471 Ende
3478*cdf0e10cSrcweir 
3479*cdf0e10cSrcweir 		sal_Int16 nWinStyle = 0;
3480*cdf0e10cSrcweir 		if( nArgCount >= 3 )
3481*cdf0e10cSrcweir 		{
3482*cdf0e10cSrcweir 			nWinStyle = rPar.Get(2)->GetInteger();
3483*cdf0e10cSrcweir 			switch( nWinStyle )
3484*cdf0e10cSrcweir 			{
3485*cdf0e10cSrcweir 				case 2:
3486*cdf0e10cSrcweir 					nOptions |= vos::OProcess::TOption_Minimized;
3487*cdf0e10cSrcweir 					break;
3488*cdf0e10cSrcweir 				case 3:
3489*cdf0e10cSrcweir 					nOptions |= vos::OProcess::TOption_Maximized;
3490*cdf0e10cSrcweir 					break;
3491*cdf0e10cSrcweir 				case 10:
3492*cdf0e10cSrcweir 					nOptions |= vos::OProcess::TOption_FullScreen;
3493*cdf0e10cSrcweir 					break;
3494*cdf0e10cSrcweir 			}
3495*cdf0e10cSrcweir 
3496*cdf0e10cSrcweir 			sal_Bool bSync = sal_False;
3497*cdf0e10cSrcweir 			if( nArgCount >= 5 )
3498*cdf0e10cSrcweir 				bSync = rPar.Get(4)->GetBool();
3499*cdf0e10cSrcweir 			if( bSync )
3500*cdf0e10cSrcweir 				nOptions |= vos::OProcess::TOption_Wait;
3501*cdf0e10cSrcweir 		}
3502*cdf0e10cSrcweir 		vos::OProcess::TProcessOption eOptions =
3503*cdf0e10cSrcweir 			(vos::OProcess::TProcessOption)nOptions;
3504*cdf0e10cSrcweir 
3505*cdf0e10cSrcweir 
3506*cdf0e10cSrcweir 		// #72471 Parameter aufbereiten
3507*cdf0e10cSrcweir 		std::list<String>::const_iterator iter = aTokenList.begin();
3508*cdf0e10cSrcweir 		const String& rStr = *iter;
3509*cdf0e10cSrcweir 		::rtl::OUString aOUStrProg( rStr.GetBuffer(), rStr.Len() );
3510*cdf0e10cSrcweir 		String aOUStrProgUNC = getFullPathUNC( aOUStrProg );
3511*cdf0e10cSrcweir 
3512*cdf0e10cSrcweir 		iter++;
3513*cdf0e10cSrcweir 
3514*cdf0e10cSrcweir 		sal_uInt16 nParamCount = sal::static_int_cast< sal_uInt16 >(
3515*cdf0e10cSrcweir             aTokenList.size() - 1 );
3516*cdf0e10cSrcweir 		::rtl::OUString* pArgumentList = NULL;
3517*cdf0e10cSrcweir 		//const char** pParamList = NULL;
3518*cdf0e10cSrcweir 		if( nParamCount )
3519*cdf0e10cSrcweir 		{
3520*cdf0e10cSrcweir 			pArgumentList = new ::rtl::OUString[ nParamCount ];
3521*cdf0e10cSrcweir 			//pParamList = new const char*[ nParamCount ];
3522*cdf0e10cSrcweir 			sal_uInt16 iList = 0;
3523*cdf0e10cSrcweir 			while( iter != aTokenList.end() )
3524*cdf0e10cSrcweir 			{
3525*cdf0e10cSrcweir 				const String& rParamStr = (*iter);
3526*cdf0e10cSrcweir 				pArgumentList[iList++] = ::rtl::OUString( rParamStr.GetBuffer(), rParamStr.Len() );
3527*cdf0e10cSrcweir 				//pParamList[iList++] = (*iter).GetStr();
3528*cdf0e10cSrcweir 				iter++;
3529*cdf0e10cSrcweir 			}
3530*cdf0e10cSrcweir 		}
3531*cdf0e10cSrcweir 
3532*cdf0e10cSrcweir 		//const char* pParams = aParams.Len() ? aParams.GetStr() : 0;
3533*cdf0e10cSrcweir 		vos::OProcess* pApp;
3534*cdf0e10cSrcweir 		pApp = new vos::OProcess( aOUStrProgUNC );
3535*cdf0e10cSrcweir 		sal_Bool bSucc;
3536*cdf0e10cSrcweir 		if( nParamCount == 0 )
3537*cdf0e10cSrcweir 		{
3538*cdf0e10cSrcweir 			bSucc = pApp->execute( eOptions ) == vos::OProcess::E_None;
3539*cdf0e10cSrcweir 		}
3540*cdf0e10cSrcweir 		else
3541*cdf0e10cSrcweir 		{
3542*cdf0e10cSrcweir 		    vos::OArgumentList aArgList( pArgumentList, nParamCount );
3543*cdf0e10cSrcweir 			bSucc = pApp->execute( eOptions, aArgList ) == vos::OProcess::E_None;
3544*cdf0e10cSrcweir 		}
3545*cdf0e10cSrcweir 
3546*cdf0e10cSrcweir 		/*
3547*cdf0e10cSrcweir 		if( nParamCount == 0 )
3548*cdf0e10cSrcweir 			pApp = new vos::OProcess( pProg );
3549*cdf0e10cSrcweir 		else
3550*cdf0e10cSrcweir 			pApp = new vos::OProcess( pProg, pParamList, nParamCount );
3551*cdf0e10cSrcweir 		sal_Bool bSucc = pApp->execute( eOptions ) == vos::OProcess::E_None;
3552*cdf0e10cSrcweir 		*/
3553*cdf0e10cSrcweir 
3554*cdf0e10cSrcweir 		delete pApp;
3555*cdf0e10cSrcweir 		delete[] pArgumentList;
3556*cdf0e10cSrcweir 		if( !bSucc )
3557*cdf0e10cSrcweir 			StarBASIC::Error( SbERR_FILE_NOT_FOUND );
3558*cdf0e10cSrcweir 		else
3559*cdf0e10cSrcweir 			rPar.Get(0)->PutLong( 0 );
3560*cdf0e10cSrcweir 	}
3561*cdf0e10cSrcweir }
3562*cdf0e10cSrcweir 
3563*cdf0e10cSrcweir RTLFUNC(VarType)
3564*cdf0e10cSrcweir {
3565*cdf0e10cSrcweir     (void)pBasic;
3566*cdf0e10cSrcweir     (void)bWrite;
3567*cdf0e10cSrcweir 
3568*cdf0e10cSrcweir 	if ( rPar.Count() != 2 )
3569*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
3570*cdf0e10cSrcweir 	else
3571*cdf0e10cSrcweir 	{
3572*cdf0e10cSrcweir 		SbxDataType eType = rPar.Get(1)->GetType();
3573*cdf0e10cSrcweir 		rPar.Get(0)->PutInteger( (sal_Int16)eType );
3574*cdf0e10cSrcweir 	}
3575*cdf0e10cSrcweir }
3576*cdf0e10cSrcweir 
3577*cdf0e10cSrcweir // Exported function
3578*cdf0e10cSrcweir String getBasicTypeName( SbxDataType eType )
3579*cdf0e10cSrcweir {
3580*cdf0e10cSrcweir 	static const char* pTypeNames[] =
3581*cdf0e10cSrcweir 	{
3582*cdf0e10cSrcweir 		"Empty",            // SbxEMPTY
3583*cdf0e10cSrcweir 		"Null",             // SbxNULL
3584*cdf0e10cSrcweir 		"Integer",          // SbxINTEGER
3585*cdf0e10cSrcweir 		"Long",             // SbxLONG
3586*cdf0e10cSrcweir 		"Single",           // SbxSINGLE
3587*cdf0e10cSrcweir 		"Double",           // SbxDOUBLE
3588*cdf0e10cSrcweir 		"Currency",         // SbxCURRENCY
3589*cdf0e10cSrcweir 		"Date",             // SbxDATE
3590*cdf0e10cSrcweir 		"String",           // SbxSTRING
3591*cdf0e10cSrcweir 		"Object",           // SbxOBJECT
3592*cdf0e10cSrcweir 		"Error",            // SbxERROR
3593*cdf0e10cSrcweir 		"Boolean",          // SbxBOOL
3594*cdf0e10cSrcweir 		"Variant",          // SbxVARIANT
3595*cdf0e10cSrcweir 		"DataObject",       // SbxDATAOBJECT
3596*cdf0e10cSrcweir 		"Unknown Type",     //
3597*cdf0e10cSrcweir 		"Unknown Type",     //
3598*cdf0e10cSrcweir 		"Char",             // SbxCHAR
3599*cdf0e10cSrcweir 		"Byte",             // SbxBYTE
3600*cdf0e10cSrcweir 		"UShort",           // SbxUSHORT
3601*cdf0e10cSrcweir 		"ULong",            // SbxULONG
3602*cdf0e10cSrcweir 		"Long64",           // SbxLONG64
3603*cdf0e10cSrcweir 		"ULong64",          // SbxULONG64
3604*cdf0e10cSrcweir 		"Int",              // SbxINT
3605*cdf0e10cSrcweir 		"UInt",             // SbxUINT
3606*cdf0e10cSrcweir 		"Void",             // SbxVOID
3607*cdf0e10cSrcweir 		"HResult",          // SbxHRESULT
3608*cdf0e10cSrcweir 		"Pointer",          // SbxPOINTER
3609*cdf0e10cSrcweir 		"DimArray",         // SbxDIMARRAY
3610*cdf0e10cSrcweir 		"CArray",           // SbxCARRAY
3611*cdf0e10cSrcweir 		"Userdef",          // SbxUSERDEF
3612*cdf0e10cSrcweir 		"Lpstr",            // SbxLPSTR
3613*cdf0e10cSrcweir 		"Lpwstr",           // SbxLPWSTR
3614*cdf0e10cSrcweir 		"Unknown Type",     // SbxCoreSTRING
3615*cdf0e10cSrcweir 		"WString",          // SbxWSTRING
3616*cdf0e10cSrcweir 		"WChar",            // SbxWCHAR
3617*cdf0e10cSrcweir 		"Int64",            // SbxSALINT64
3618*cdf0e10cSrcweir 		"UInt64",           // SbxSALUINT64
3619*cdf0e10cSrcweir 		"Decimal",          // SbxDECIMAL
3620*cdf0e10cSrcweir 	};
3621*cdf0e10cSrcweir 
3622*cdf0e10cSrcweir 	int nPos = ((int)eType) & 0x0FFF;
3623*cdf0e10cSrcweir 	sal_uInt16 nTypeNameCount = sizeof( pTypeNames ) / sizeof( char* );
3624*cdf0e10cSrcweir 	if ( nPos < 0 || nPos >= nTypeNameCount )
3625*cdf0e10cSrcweir 		nPos = nTypeNameCount - 1;
3626*cdf0e10cSrcweir 	String aRetStr = String::CreateFromAscii( pTypeNames[nPos] );
3627*cdf0e10cSrcweir 	return aRetStr;
3628*cdf0e10cSrcweir }
3629*cdf0e10cSrcweir 
3630*cdf0e10cSrcweir RTLFUNC(TypeName)
3631*cdf0e10cSrcweir {
3632*cdf0e10cSrcweir     (void)pBasic;
3633*cdf0e10cSrcweir     (void)bWrite;
3634*cdf0e10cSrcweir 
3635*cdf0e10cSrcweir 	if ( rPar.Count() != 2 )
3636*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
3637*cdf0e10cSrcweir 	else
3638*cdf0e10cSrcweir 	{
3639*cdf0e10cSrcweir 		SbxDataType eType = rPar.Get(1)->GetType();
3640*cdf0e10cSrcweir 		sal_Bool bIsArray = ( ( eType & SbxARRAY ) != 0 );
3641*cdf0e10cSrcweir 		String aRetStr = getBasicTypeName( eType );
3642*cdf0e10cSrcweir 		if( bIsArray )
3643*cdf0e10cSrcweir 			aRetStr.AppendAscii( "()" );
3644*cdf0e10cSrcweir 		rPar.Get(0)->PutString( aRetStr );
3645*cdf0e10cSrcweir 	}
3646*cdf0e10cSrcweir }
3647*cdf0e10cSrcweir 
3648*cdf0e10cSrcweir RTLFUNC(Len)
3649*cdf0e10cSrcweir {
3650*cdf0e10cSrcweir     (void)pBasic;
3651*cdf0e10cSrcweir     (void)bWrite;
3652*cdf0e10cSrcweir 
3653*cdf0e10cSrcweir 	if ( rPar.Count() != 2 )
3654*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
3655*cdf0e10cSrcweir 	else
3656*cdf0e10cSrcweir 	{
3657*cdf0e10cSrcweir 		const String& rStr = rPar.Get(1)->GetString();
3658*cdf0e10cSrcweir 		rPar.Get(0)->PutLong( (sal_Int32)rStr.Len() );
3659*cdf0e10cSrcweir 	}
3660*cdf0e10cSrcweir }
3661*cdf0e10cSrcweir 
3662*cdf0e10cSrcweir RTLFUNC(DDEInitiate)
3663*cdf0e10cSrcweir {
3664*cdf0e10cSrcweir     (void)pBasic;
3665*cdf0e10cSrcweir     (void)bWrite;
3666*cdf0e10cSrcweir 
3667*cdf0e10cSrcweir 	// No DDE for "virtual" portal users
3668*cdf0e10cSrcweir 	if( needSecurityRestrictions() )
3669*cdf0e10cSrcweir 	{
3670*cdf0e10cSrcweir 		StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
3671*cdf0e10cSrcweir 		return;
3672*cdf0e10cSrcweir 	}
3673*cdf0e10cSrcweir 
3674*cdf0e10cSrcweir 	int nArgs = (int)rPar.Count();
3675*cdf0e10cSrcweir 	if ( nArgs != 3 )
3676*cdf0e10cSrcweir 	{
3677*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
3678*cdf0e10cSrcweir 		return;
3679*cdf0e10cSrcweir 	}
3680*cdf0e10cSrcweir 	const String& rApp = rPar.Get(1)->GetString();
3681*cdf0e10cSrcweir 	const String& rTopic = rPar.Get(2)->GetString();
3682*cdf0e10cSrcweir 
3683*cdf0e10cSrcweir 	SbiDdeControl* pDDE = pINST->GetDdeControl();
3684*cdf0e10cSrcweir 	sal_Int16 nChannel;
3685*cdf0e10cSrcweir 	SbError nDdeErr = pDDE->Initiate( rApp, rTopic, nChannel );
3686*cdf0e10cSrcweir 	if( nDdeErr )
3687*cdf0e10cSrcweir 		StarBASIC::Error( nDdeErr );
3688*cdf0e10cSrcweir 	else
3689*cdf0e10cSrcweir 		rPar.Get(0)->PutInteger( nChannel );
3690*cdf0e10cSrcweir }
3691*cdf0e10cSrcweir 
3692*cdf0e10cSrcweir RTLFUNC(DDETerminate)
3693*cdf0e10cSrcweir {
3694*cdf0e10cSrcweir     (void)pBasic;
3695*cdf0e10cSrcweir     (void)bWrite;
3696*cdf0e10cSrcweir 
3697*cdf0e10cSrcweir 	// No DDE for "virtual" portal users
3698*cdf0e10cSrcweir 	if( needSecurityRestrictions() )
3699*cdf0e10cSrcweir 	{
3700*cdf0e10cSrcweir 		StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
3701*cdf0e10cSrcweir 		return;
3702*cdf0e10cSrcweir 	}
3703*cdf0e10cSrcweir 
3704*cdf0e10cSrcweir 	rPar.Get(0)->PutEmpty();
3705*cdf0e10cSrcweir 	int nArgs = (int)rPar.Count();
3706*cdf0e10cSrcweir 	if ( nArgs != 2 )
3707*cdf0e10cSrcweir 	{
3708*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
3709*cdf0e10cSrcweir 		return;
3710*cdf0e10cSrcweir 	}
3711*cdf0e10cSrcweir 	sal_Int16 nChannel = rPar.Get(1)->GetInteger();
3712*cdf0e10cSrcweir 	SbiDdeControl* pDDE = pINST->GetDdeControl();
3713*cdf0e10cSrcweir 	SbError nDdeErr = pDDE->Terminate( nChannel );
3714*cdf0e10cSrcweir 	if( nDdeErr )
3715*cdf0e10cSrcweir 		StarBASIC::Error( nDdeErr );
3716*cdf0e10cSrcweir }
3717*cdf0e10cSrcweir 
3718*cdf0e10cSrcweir RTLFUNC(DDETerminateAll)
3719*cdf0e10cSrcweir {
3720*cdf0e10cSrcweir     (void)pBasic;
3721*cdf0e10cSrcweir     (void)bWrite;
3722*cdf0e10cSrcweir 
3723*cdf0e10cSrcweir 	// No DDE for "virtual" portal users
3724*cdf0e10cSrcweir 	if( needSecurityRestrictions() )
3725*cdf0e10cSrcweir 	{
3726*cdf0e10cSrcweir 		StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
3727*cdf0e10cSrcweir 		return;
3728*cdf0e10cSrcweir 	}
3729*cdf0e10cSrcweir 
3730*cdf0e10cSrcweir 	rPar.Get(0)->PutEmpty();
3731*cdf0e10cSrcweir 	int nArgs = (int)rPar.Count();
3732*cdf0e10cSrcweir 	if ( nArgs != 1 )
3733*cdf0e10cSrcweir 	{
3734*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
3735*cdf0e10cSrcweir 		return;
3736*cdf0e10cSrcweir 	}
3737*cdf0e10cSrcweir 
3738*cdf0e10cSrcweir 	SbiDdeControl* pDDE = pINST->GetDdeControl();
3739*cdf0e10cSrcweir 	SbError nDdeErr = pDDE->TerminateAll();
3740*cdf0e10cSrcweir 	if( nDdeErr )
3741*cdf0e10cSrcweir 		StarBASIC::Error( nDdeErr );
3742*cdf0e10cSrcweir 
3743*cdf0e10cSrcweir }
3744*cdf0e10cSrcweir 
3745*cdf0e10cSrcweir RTLFUNC(DDERequest)
3746*cdf0e10cSrcweir {
3747*cdf0e10cSrcweir     (void)pBasic;
3748*cdf0e10cSrcweir     (void)bWrite;
3749*cdf0e10cSrcweir 
3750*cdf0e10cSrcweir 	// No DDE for "virtual" portal users
3751*cdf0e10cSrcweir 	if( needSecurityRestrictions() )
3752*cdf0e10cSrcweir 	{
3753*cdf0e10cSrcweir 		StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
3754*cdf0e10cSrcweir 		return;
3755*cdf0e10cSrcweir 	}
3756*cdf0e10cSrcweir 
3757*cdf0e10cSrcweir 	int nArgs = (int)rPar.Count();
3758*cdf0e10cSrcweir 	if ( nArgs != 3 )
3759*cdf0e10cSrcweir 	{
3760*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
3761*cdf0e10cSrcweir 		return;
3762*cdf0e10cSrcweir 	}
3763*cdf0e10cSrcweir 	sal_Int16 nChannel = rPar.Get(1)->GetInteger();
3764*cdf0e10cSrcweir 	const String& rItem = rPar.Get(2)->GetString();
3765*cdf0e10cSrcweir 	SbiDdeControl* pDDE = pINST->GetDdeControl();
3766*cdf0e10cSrcweir 	String aResult;
3767*cdf0e10cSrcweir 	SbError nDdeErr = pDDE->Request( nChannel, rItem, aResult );
3768*cdf0e10cSrcweir 	if( nDdeErr )
3769*cdf0e10cSrcweir 		StarBASIC::Error( nDdeErr );
3770*cdf0e10cSrcweir 	else
3771*cdf0e10cSrcweir 		rPar.Get(0)->PutString( aResult );
3772*cdf0e10cSrcweir }
3773*cdf0e10cSrcweir 
3774*cdf0e10cSrcweir RTLFUNC(DDEExecute)
3775*cdf0e10cSrcweir {
3776*cdf0e10cSrcweir     (void)pBasic;
3777*cdf0e10cSrcweir     (void)bWrite;
3778*cdf0e10cSrcweir 
3779*cdf0e10cSrcweir 	// No DDE for "virtual" portal users
3780*cdf0e10cSrcweir 	if( needSecurityRestrictions() )
3781*cdf0e10cSrcweir 	{
3782*cdf0e10cSrcweir 		StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
3783*cdf0e10cSrcweir 		return;
3784*cdf0e10cSrcweir 	}
3785*cdf0e10cSrcweir 
3786*cdf0e10cSrcweir 	rPar.Get(0)->PutEmpty();
3787*cdf0e10cSrcweir 	int nArgs = (int)rPar.Count();
3788*cdf0e10cSrcweir 	if ( nArgs != 3 )
3789*cdf0e10cSrcweir 	{
3790*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
3791*cdf0e10cSrcweir 		return;
3792*cdf0e10cSrcweir 	}
3793*cdf0e10cSrcweir 	sal_Int16 nChannel = rPar.Get(1)->GetInteger();
3794*cdf0e10cSrcweir 	const String& rCommand = rPar.Get(2)->GetString();
3795*cdf0e10cSrcweir 	SbiDdeControl* pDDE = pINST->GetDdeControl();
3796*cdf0e10cSrcweir 	SbError nDdeErr = pDDE->Execute( nChannel, rCommand );
3797*cdf0e10cSrcweir 	if( nDdeErr )
3798*cdf0e10cSrcweir 		StarBASIC::Error( nDdeErr );
3799*cdf0e10cSrcweir }
3800*cdf0e10cSrcweir 
3801*cdf0e10cSrcweir RTLFUNC(DDEPoke)
3802*cdf0e10cSrcweir {
3803*cdf0e10cSrcweir     (void)pBasic;
3804*cdf0e10cSrcweir     (void)bWrite;
3805*cdf0e10cSrcweir 
3806*cdf0e10cSrcweir 	// No DDE for "virtual" portal users
3807*cdf0e10cSrcweir 	if( needSecurityRestrictions() )
3808*cdf0e10cSrcweir 	{
3809*cdf0e10cSrcweir 		StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
3810*cdf0e10cSrcweir 		return;
3811*cdf0e10cSrcweir 	}
3812*cdf0e10cSrcweir 
3813*cdf0e10cSrcweir 	rPar.Get(0)->PutEmpty();
3814*cdf0e10cSrcweir 	int nArgs = (int)rPar.Count();
3815*cdf0e10cSrcweir 	if ( nArgs != 4 )
3816*cdf0e10cSrcweir 	{
3817*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
3818*cdf0e10cSrcweir 		return;
3819*cdf0e10cSrcweir 	}
3820*cdf0e10cSrcweir 	sal_Int16 nChannel = rPar.Get(1)->GetInteger();
3821*cdf0e10cSrcweir 	const String& rItem = rPar.Get(2)->GetString();
3822*cdf0e10cSrcweir 	const String& rData = rPar.Get(3)->GetString();
3823*cdf0e10cSrcweir 	SbiDdeControl* pDDE = pINST->GetDdeControl();
3824*cdf0e10cSrcweir 	SbError nDdeErr = pDDE->Poke( nChannel, rItem, rData );
3825*cdf0e10cSrcweir 	if( nDdeErr )
3826*cdf0e10cSrcweir 		StarBASIC::Error( nDdeErr );
3827*cdf0e10cSrcweir }
3828*cdf0e10cSrcweir 
3829*cdf0e10cSrcweir 
3830*cdf0e10cSrcweir RTLFUNC(FreeFile)
3831*cdf0e10cSrcweir {
3832*cdf0e10cSrcweir     (void)pBasic;
3833*cdf0e10cSrcweir     (void)bWrite;
3834*cdf0e10cSrcweir 
3835*cdf0e10cSrcweir 	if ( rPar.Count() != 1 )
3836*cdf0e10cSrcweir 	{
3837*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
3838*cdf0e10cSrcweir 		return;
3839*cdf0e10cSrcweir 	}
3840*cdf0e10cSrcweir 	SbiIoSystem* pIO = pINST->GetIoSystem();
3841*cdf0e10cSrcweir 	short nChannel = 1;
3842*cdf0e10cSrcweir 	while( nChannel < CHANNELS )
3843*cdf0e10cSrcweir 	{
3844*cdf0e10cSrcweir 		SbiStream* pStrm = pIO->GetStream( nChannel );
3845*cdf0e10cSrcweir 		if( !pStrm )
3846*cdf0e10cSrcweir 		{
3847*cdf0e10cSrcweir 			rPar.Get(0)->PutInteger( nChannel );
3848*cdf0e10cSrcweir 			return;
3849*cdf0e10cSrcweir 		}
3850*cdf0e10cSrcweir 		nChannel++;
3851*cdf0e10cSrcweir 	}
3852*cdf0e10cSrcweir 	StarBASIC::Error( SbERR_TOO_MANY_FILES );
3853*cdf0e10cSrcweir }
3854*cdf0e10cSrcweir 
3855*cdf0e10cSrcweir RTLFUNC(LBound)
3856*cdf0e10cSrcweir {
3857*cdf0e10cSrcweir     (void)pBasic;
3858*cdf0e10cSrcweir     (void)bWrite;
3859*cdf0e10cSrcweir 
3860*cdf0e10cSrcweir 	sal_uInt16 nParCount = rPar.Count();
3861*cdf0e10cSrcweir 	if ( nParCount != 3 && nParCount != 2 )
3862*cdf0e10cSrcweir 	{
3863*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
3864*cdf0e10cSrcweir 		return;
3865*cdf0e10cSrcweir 	}
3866*cdf0e10cSrcweir 	SbxBase* pParObj = rPar.Get(1)->GetObject();
3867*cdf0e10cSrcweir 	SbxDimArray* pArr = PTR_CAST(SbxDimArray,pParObj);
3868*cdf0e10cSrcweir 	if( pArr )
3869*cdf0e10cSrcweir 	{
3870*cdf0e10cSrcweir 		sal_Int32 nLower, nUpper;
3871*cdf0e10cSrcweir 		short nDim = (nParCount == 3) ? (short)rPar.Get(2)->GetInteger() : 1;
3872*cdf0e10cSrcweir 		if( !pArr->GetDim32( nDim, nLower, nUpper ) )
3873*cdf0e10cSrcweir 			StarBASIC::Error( SbERR_OUT_OF_RANGE );
3874*cdf0e10cSrcweir 		else
3875*cdf0e10cSrcweir 			rPar.Get(0)->PutLong( nLower );
3876*cdf0e10cSrcweir 	}
3877*cdf0e10cSrcweir 	else
3878*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_MUST_HAVE_DIMS );
3879*cdf0e10cSrcweir }
3880*cdf0e10cSrcweir 
3881*cdf0e10cSrcweir RTLFUNC(UBound)
3882*cdf0e10cSrcweir {
3883*cdf0e10cSrcweir     (void)pBasic;
3884*cdf0e10cSrcweir     (void)bWrite;
3885*cdf0e10cSrcweir 
3886*cdf0e10cSrcweir 	sal_uInt16 nParCount = rPar.Count();
3887*cdf0e10cSrcweir 	if ( nParCount != 3 && nParCount != 2 )
3888*cdf0e10cSrcweir 	{
3889*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
3890*cdf0e10cSrcweir 		return;
3891*cdf0e10cSrcweir 	}
3892*cdf0e10cSrcweir 
3893*cdf0e10cSrcweir 	SbxBase* pParObj = rPar.Get(1)->GetObject();
3894*cdf0e10cSrcweir 	SbxDimArray* pArr = PTR_CAST(SbxDimArray,pParObj);
3895*cdf0e10cSrcweir 	if( pArr )
3896*cdf0e10cSrcweir 	{
3897*cdf0e10cSrcweir 		sal_Int32 nLower, nUpper;
3898*cdf0e10cSrcweir 		short nDim = (nParCount == 3) ? (short)rPar.Get(2)->GetInteger() : 1;
3899*cdf0e10cSrcweir 		if( !pArr->GetDim32( nDim, nLower, nUpper ) )
3900*cdf0e10cSrcweir 			StarBASIC::Error( SbERR_OUT_OF_RANGE );
3901*cdf0e10cSrcweir 		else
3902*cdf0e10cSrcweir 			rPar.Get(0)->PutLong( nUpper );
3903*cdf0e10cSrcweir 	}
3904*cdf0e10cSrcweir 	else
3905*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_MUST_HAVE_DIMS );
3906*cdf0e10cSrcweir }
3907*cdf0e10cSrcweir 
3908*cdf0e10cSrcweir RTLFUNC(RGB)
3909*cdf0e10cSrcweir {
3910*cdf0e10cSrcweir     (void)pBasic;
3911*cdf0e10cSrcweir     (void)bWrite;
3912*cdf0e10cSrcweir 
3913*cdf0e10cSrcweir 	if ( rPar.Count() != 4 )
3914*cdf0e10cSrcweir 	{
3915*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
3916*cdf0e10cSrcweir 		return;
3917*cdf0e10cSrcweir 	}
3918*cdf0e10cSrcweir 
3919*cdf0e10cSrcweir 	sal_uIntPtr nRed	 = rPar.Get(1)->GetInteger() & 0xFF;
3920*cdf0e10cSrcweir 	sal_uIntPtr nGreen = rPar.Get(2)->GetInteger() & 0xFF;
3921*cdf0e10cSrcweir 	sal_uIntPtr nBlue  = rPar.Get(3)->GetInteger() & 0xFF;
3922*cdf0e10cSrcweir 	sal_uIntPtr nRGB;
3923*cdf0e10cSrcweir 
3924*cdf0e10cSrcweir 	SbiInstance* pInst = pINST;
3925*cdf0e10cSrcweir 	bool bCompatibility = ( pInst && pInst->IsCompatibility() );
3926*cdf0e10cSrcweir 	if( bCompatibility )
3927*cdf0e10cSrcweir 	{
3928*cdf0e10cSrcweir 		nRGB   = (nBlue << 16) | (nGreen << 8) | nRed;
3929*cdf0e10cSrcweir 	}
3930*cdf0e10cSrcweir 	else
3931*cdf0e10cSrcweir 	{
3932*cdf0e10cSrcweir 		nRGB   = (nRed << 16) | (nGreen << 8) | nBlue;
3933*cdf0e10cSrcweir 	}
3934*cdf0e10cSrcweir 	rPar.Get(0)->PutLong( nRGB );
3935*cdf0e10cSrcweir }
3936*cdf0e10cSrcweir 
3937*cdf0e10cSrcweir RTLFUNC(QBColor)
3938*cdf0e10cSrcweir {
3939*cdf0e10cSrcweir     (void)pBasic;
3940*cdf0e10cSrcweir     (void)bWrite;
3941*cdf0e10cSrcweir 
3942*cdf0e10cSrcweir 	static const sal_Int32 pRGB[] =
3943*cdf0e10cSrcweir 	{
3944*cdf0e10cSrcweir 		0x000000,
3945*cdf0e10cSrcweir 		0x800000,
3946*cdf0e10cSrcweir 		0x008000,
3947*cdf0e10cSrcweir 		0x808000,
3948*cdf0e10cSrcweir 		0x000080,
3949*cdf0e10cSrcweir 		0x800080,
3950*cdf0e10cSrcweir 		0x008080,
3951*cdf0e10cSrcweir 		0xC0C0C0,
3952*cdf0e10cSrcweir 		0x808080,
3953*cdf0e10cSrcweir 		0xFF0000,
3954*cdf0e10cSrcweir 		0x00FF00,
3955*cdf0e10cSrcweir 		0xFFFF00,
3956*cdf0e10cSrcweir 		0x0000FF,
3957*cdf0e10cSrcweir 		0xFF00FF,
3958*cdf0e10cSrcweir 		0x00FFFF,
3959*cdf0e10cSrcweir 		0xFFFFFF,
3960*cdf0e10cSrcweir 	};
3961*cdf0e10cSrcweir 
3962*cdf0e10cSrcweir 	if ( rPar.Count() != 2 )
3963*cdf0e10cSrcweir 	{
3964*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
3965*cdf0e10cSrcweir 		return;
3966*cdf0e10cSrcweir 	}
3967*cdf0e10cSrcweir 
3968*cdf0e10cSrcweir 	sal_Int16 nCol = rPar.Get(1)->GetInteger();
3969*cdf0e10cSrcweir 	if( nCol < 0 || nCol > 15 )
3970*cdf0e10cSrcweir 	{
3971*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
3972*cdf0e10cSrcweir 		return;
3973*cdf0e10cSrcweir 	}
3974*cdf0e10cSrcweir 	sal_Int32 nRGB = pRGB[ nCol ];
3975*cdf0e10cSrcweir 	rPar.Get(0)->PutLong( nRGB );
3976*cdf0e10cSrcweir }
3977*cdf0e10cSrcweir 
3978*cdf0e10cSrcweir // StrConv(string, conversion, LCID)
3979*cdf0e10cSrcweir RTLFUNC(StrConv)
3980*cdf0e10cSrcweir {
3981*cdf0e10cSrcweir     (void)pBasic;
3982*cdf0e10cSrcweir     (void)bWrite;
3983*cdf0e10cSrcweir 
3984*cdf0e10cSrcweir 	sal_uIntPtr nArgCount = rPar.Count()-1;
3985*cdf0e10cSrcweir 	if( nArgCount < 2 || nArgCount > 3 )
3986*cdf0e10cSrcweir 	{
3987*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
3988*cdf0e10cSrcweir 		return;
3989*cdf0e10cSrcweir 	}
3990*cdf0e10cSrcweir 
3991*cdf0e10cSrcweir 	String aOldStr = rPar.Get(1)->GetString();
3992*cdf0e10cSrcweir 	sal_Int32 nConversion = rPar.Get(2)->GetLong();
3993*cdf0e10cSrcweir 
3994*cdf0e10cSrcweir 	sal_uInt16 nLanguage = LANGUAGE_SYSTEM;
3995*cdf0e10cSrcweir 	if( nArgCount == 3 )
3996*cdf0e10cSrcweir 	{
3997*cdf0e10cSrcweir 		// LCID not supported now
3998*cdf0e10cSrcweir 		//nLanguage = rPar.Get(3)->GetInteger();
3999*cdf0e10cSrcweir 	}
4000*cdf0e10cSrcweir 
4001*cdf0e10cSrcweir 	sal_uInt16 nOldLen = aOldStr.Len();
4002*cdf0e10cSrcweir 	if( nOldLen == 0 )
4003*cdf0e10cSrcweir 	{
4004*cdf0e10cSrcweir 		// null string,return
4005*cdf0e10cSrcweir 		rPar.Get(0)->PutString(aOldStr);
4006*cdf0e10cSrcweir 		return;
4007*cdf0e10cSrcweir 	}
4008*cdf0e10cSrcweir 
4009*cdf0e10cSrcweir 	sal_Int32 nType = 0;
4010*cdf0e10cSrcweir 	if ( (nConversion & 0x03) == 3 ) //  vbProperCase
4011*cdf0e10cSrcweir 	{
4012*cdf0e10cSrcweir 		CharClass& rCharClass = GetCharClass();
4013*cdf0e10cSrcweir 		aOldStr = rCharClass.toTitle( aOldStr.ToLowerAscii(), 0, nOldLen );
4014*cdf0e10cSrcweir 	}
4015*cdf0e10cSrcweir 	else if ( (nConversion & 0x01) == 1 ) // vbUpperCase
4016*cdf0e10cSrcweir 		nType |= ::com::sun::star::i18n::TransliterationModules_LOWERCASE_UPPERCASE;
4017*cdf0e10cSrcweir 	else if ( (nConversion & 0x02) == 2 ) // vbLowerCase
4018*cdf0e10cSrcweir 		nType |= ::com::sun::star::i18n::TransliterationModules_UPPERCASE_LOWERCASE;
4019*cdf0e10cSrcweir 
4020*cdf0e10cSrcweir 	if ( (nConversion & 0x04) == 4 ) // vbWide
4021*cdf0e10cSrcweir 		nType |= ::com::sun::star::i18n::TransliterationModules_HALFWIDTH_FULLWIDTH;
4022*cdf0e10cSrcweir 	else if ( (nConversion & 0x08) == 8 ) // vbNarrow
4023*cdf0e10cSrcweir 		nType |= ::com::sun::star::i18n::TransliterationModules_FULLWIDTH_HALFWIDTH;
4024*cdf0e10cSrcweir 
4025*cdf0e10cSrcweir 	if ( (nConversion & 0x10) == 16) // vbKatakana
4026*cdf0e10cSrcweir 		nType |= ::com::sun::star::i18n::TransliterationModules_HIRAGANA_KATAKANA;
4027*cdf0e10cSrcweir 	else if ( (nConversion & 0x20) == 32 ) // vbHiragana
4028*cdf0e10cSrcweir 		nType |= ::com::sun::star::i18n::TransliterationModules_KATAKANA_HIRAGANA;
4029*cdf0e10cSrcweir 
4030*cdf0e10cSrcweir 	String aNewStr( aOldStr );
4031*cdf0e10cSrcweir 	if( nType != 0 )
4032*cdf0e10cSrcweir 	{
4033*cdf0e10cSrcweir 		com::sun::star::uno::Reference< XMultiServiceFactory > xSMgr = getProcessServiceFactory();
4034*cdf0e10cSrcweir     	::utl::TransliterationWrapper aTransliterationWrapper( xSMgr,nType );
4035*cdf0e10cSrcweir 		com::sun::star::uno::Sequence<sal_Int32> aOffsets;
4036*cdf0e10cSrcweir 		aTransliterationWrapper.loadModuleIfNeeded( nLanguage );
4037*cdf0e10cSrcweir 		aNewStr = aTransliterationWrapper.transliterate( aOldStr, nLanguage, 0, nOldLen, &aOffsets );
4038*cdf0e10cSrcweir 	}
4039*cdf0e10cSrcweir 
4040*cdf0e10cSrcweir 	if ( (nConversion & 0x40) == 64 ) // vbUnicode
4041*cdf0e10cSrcweir 	{
4042*cdf0e10cSrcweir 		// convert the string to byte string, preserving unicode (2 bytes per character)
4043*cdf0e10cSrcweir 		sal_uInt16 nSize = aNewStr.Len()*2;
4044*cdf0e10cSrcweir 		const sal_Unicode* pSrc = aNewStr.GetBuffer();
4045*cdf0e10cSrcweir 		sal_Char* pChar = new sal_Char[nSize+1];
4046*cdf0e10cSrcweir 		for( sal_uInt16 i=0; i < nSize; i++ )
4047*cdf0e10cSrcweir 		{
4048*cdf0e10cSrcweir 			pChar[i] = static_cast< sal_Char >( i%2 ? ((*pSrc) >> 8) & 0xff : (*pSrc) & 0xff );
4049*cdf0e10cSrcweir 			if( i%2 )
4050*cdf0e10cSrcweir 				pSrc++;
4051*cdf0e10cSrcweir 		}
4052*cdf0e10cSrcweir 		pChar[nSize] = '\0';
4053*cdf0e10cSrcweir 		::rtl::OString aOStr(pChar);
4054*cdf0e10cSrcweir 
4055*cdf0e10cSrcweir 		// there is no concept about default codepage in unix. so it is incorrectly in unix
4056*cdf0e10cSrcweir 		::rtl::OUString aOUStr = ::rtl::OStringToOUString(aOStr, osl_getThreadTextEncoding());
4057*cdf0e10cSrcweir 		aNewStr = String(aOUStr);
4058*cdf0e10cSrcweir 		rPar.Get(0)->PutString( aNewStr );
4059*cdf0e10cSrcweir 		return;
4060*cdf0e10cSrcweir 	}
4061*cdf0e10cSrcweir 	else if ( (nConversion & 0x80) == 128 ) // vbFromUnicode
4062*cdf0e10cSrcweir 	{
4063*cdf0e10cSrcweir 		::rtl::OUString aOUStr(aNewStr);
4064*cdf0e10cSrcweir 		// there is no concept about default codepage in unix. so it is incorrectly in unix
4065*cdf0e10cSrcweir 		::rtl::OString aOStr = ::rtl::OUStringToOString(aNewStr,osl_getThreadTextEncoding());
4066*cdf0e10cSrcweir 		const sal_Char* pChar = aOStr.getStr();
4067*cdf0e10cSrcweir 		sal_uInt16 nArraySize = static_cast< sal_uInt16 >( aOStr.getLength() );
4068*cdf0e10cSrcweir 		SbxDimArray* pArray = new SbxDimArray(SbxBYTE);
4069*cdf0e10cSrcweir 		bool bIncIndex = (IsBaseIndexOne() && SbiRuntime::isVBAEnabled() );
4070*cdf0e10cSrcweir 		if(nArraySize)
4071*cdf0e10cSrcweir 		{
4072*cdf0e10cSrcweir 			if( bIncIndex )
4073*cdf0e10cSrcweir 				pArray->AddDim( 1, nArraySize );
4074*cdf0e10cSrcweir 			else
4075*cdf0e10cSrcweir 				pArray->AddDim( 0, nArraySize-1 );
4076*cdf0e10cSrcweir 		}
4077*cdf0e10cSrcweir 		else
4078*cdf0e10cSrcweir 		{
4079*cdf0e10cSrcweir 			pArray->unoAddDim( 0, -1 );
4080*cdf0e10cSrcweir 		}
4081*cdf0e10cSrcweir 
4082*cdf0e10cSrcweir 		for( sal_uInt16	i=0; i< nArraySize; i++)
4083*cdf0e10cSrcweir 		{
4084*cdf0e10cSrcweir 			SbxVariable* pNew = new SbxVariable( SbxBYTE );
4085*cdf0e10cSrcweir 			pNew->PutByte(*pChar);
4086*cdf0e10cSrcweir 			pChar++;
4087*cdf0e10cSrcweir 			pNew->SetFlag( SBX_WRITE );
4088*cdf0e10cSrcweir 			short index = i;
4089*cdf0e10cSrcweir 			if( bIncIndex )
4090*cdf0e10cSrcweir 				++index;
4091*cdf0e10cSrcweir 			pArray->Put( pNew, &index );
4092*cdf0e10cSrcweir 		}
4093*cdf0e10cSrcweir 
4094*cdf0e10cSrcweir 		SbxVariableRef refVar = rPar.Get(0);
4095*cdf0e10cSrcweir 		sal_uInt16 nFlags = refVar->GetFlags();
4096*cdf0e10cSrcweir 		refVar->ResetFlag( SBX_FIXED );
4097*cdf0e10cSrcweir 		refVar->PutObject( pArray );
4098*cdf0e10cSrcweir 		refVar->SetFlags( nFlags );
4099*cdf0e10cSrcweir 	    refVar->SetParameters( NULL );
4100*cdf0e10cSrcweir    		return;
4101*cdf0e10cSrcweir 	}
4102*cdf0e10cSrcweir 
4103*cdf0e10cSrcweir 	rPar.Get(0)->PutString(aNewStr);
4104*cdf0e10cSrcweir }
4105*cdf0e10cSrcweir 
4106*cdf0e10cSrcweir 
4107*cdf0e10cSrcweir RTLFUNC(Beep)
4108*cdf0e10cSrcweir {
4109*cdf0e10cSrcweir     (void)pBasic;
4110*cdf0e10cSrcweir     (void)bWrite;
4111*cdf0e10cSrcweir 
4112*cdf0e10cSrcweir 	if ( rPar.Count() != 1 )
4113*cdf0e10cSrcweir 	{
4114*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
4115*cdf0e10cSrcweir 		return;
4116*cdf0e10cSrcweir 	}
4117*cdf0e10cSrcweir 	Sound::Beep();
4118*cdf0e10cSrcweir }
4119*cdf0e10cSrcweir 
4120*cdf0e10cSrcweir RTLFUNC(Load)
4121*cdf0e10cSrcweir {
4122*cdf0e10cSrcweir     (void)pBasic;
4123*cdf0e10cSrcweir     (void)bWrite;
4124*cdf0e10cSrcweir 
4125*cdf0e10cSrcweir 	if( rPar.Count() != 2 )
4126*cdf0e10cSrcweir 	{
4127*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
4128*cdf0e10cSrcweir 		return;
4129*cdf0e10cSrcweir 	}
4130*cdf0e10cSrcweir 
4131*cdf0e10cSrcweir 	// Diesen Call einfach an das Object weiterreichen
4132*cdf0e10cSrcweir 	SbxBase* pObj = (SbxObject*)rPar.Get(1)->GetObject();
4133*cdf0e10cSrcweir 	if ( pObj )
4134*cdf0e10cSrcweir 	{
4135*cdf0e10cSrcweir 		if( pObj->IsA( TYPE( SbUserFormModule ) ) )
4136*cdf0e10cSrcweir 		{
4137*cdf0e10cSrcweir 			((SbUserFormModule*)pObj)->Load();
4138*cdf0e10cSrcweir 		}
4139*cdf0e10cSrcweir 		else if( pObj->IsA( TYPE( SbxObject ) ) )
4140*cdf0e10cSrcweir 		{
4141*cdf0e10cSrcweir 			SbxVariable* pVar = ((SbxObject*)pObj)->
4142*cdf0e10cSrcweir 				Find( String( RTL_CONSTASCII_USTRINGPARAM("Load") ), SbxCLASS_METHOD );
4143*cdf0e10cSrcweir 			if( pVar )
4144*cdf0e10cSrcweir 				pVar->GetInteger();
4145*cdf0e10cSrcweir 		}
4146*cdf0e10cSrcweir 	}
4147*cdf0e10cSrcweir }
4148*cdf0e10cSrcweir 
4149*cdf0e10cSrcweir RTLFUNC(Unload)
4150*cdf0e10cSrcweir {
4151*cdf0e10cSrcweir     (void)pBasic;
4152*cdf0e10cSrcweir     (void)bWrite;
4153*cdf0e10cSrcweir 
4154*cdf0e10cSrcweir 	rPar.Get(0)->PutEmpty();
4155*cdf0e10cSrcweir 	if( rPar.Count() != 2 )
4156*cdf0e10cSrcweir 	{
4157*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
4158*cdf0e10cSrcweir 		return;
4159*cdf0e10cSrcweir 	}
4160*cdf0e10cSrcweir 
4161*cdf0e10cSrcweir 	// Diesen Call einfach an das Object weitereichen
4162*cdf0e10cSrcweir 	SbxBase* pObj = (SbxObject*)rPar.Get(1)->GetObject();
4163*cdf0e10cSrcweir 	if ( pObj )
4164*cdf0e10cSrcweir 	{
4165*cdf0e10cSrcweir 		if( pObj->IsA( TYPE( SbUserFormModule ) ) )
4166*cdf0e10cSrcweir 		{
4167*cdf0e10cSrcweir 			SbUserFormModule* pFormModule = ( SbUserFormModule* )pObj;
4168*cdf0e10cSrcweir 			pFormModule->Unload();
4169*cdf0e10cSrcweir 		}
4170*cdf0e10cSrcweir 		else if( pObj->IsA( TYPE( SbxObject ) ) )
4171*cdf0e10cSrcweir 		{
4172*cdf0e10cSrcweir 			SbxVariable* pVar = ((SbxObject*)pObj)->
4173*cdf0e10cSrcweir 				Find( String( RTL_CONSTASCII_USTRINGPARAM("Unload") ), SbxCLASS_METHOD );
4174*cdf0e10cSrcweir 			if( pVar )
4175*cdf0e10cSrcweir 				pVar->GetInteger();
4176*cdf0e10cSrcweir 		}
4177*cdf0e10cSrcweir 	}
4178*cdf0e10cSrcweir }
4179*cdf0e10cSrcweir 
4180*cdf0e10cSrcweir RTLFUNC(LoadPicture)
4181*cdf0e10cSrcweir {
4182*cdf0e10cSrcweir     (void)pBasic;
4183*cdf0e10cSrcweir     (void)bWrite;
4184*cdf0e10cSrcweir 
4185*cdf0e10cSrcweir 	if( rPar.Count() != 2 )
4186*cdf0e10cSrcweir 	{
4187*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
4188*cdf0e10cSrcweir 		return;
4189*cdf0e10cSrcweir 	}
4190*cdf0e10cSrcweir 
4191*cdf0e10cSrcweir 	String aFileURL = getFullPath( rPar.Get(1)->GetString() );
4192*cdf0e10cSrcweir 	SvStream* pStream = utl::UcbStreamHelper::CreateStream( aFileURL, STREAM_READ );
4193*cdf0e10cSrcweir 	if( pStream != NULL )
4194*cdf0e10cSrcweir 	{
4195*cdf0e10cSrcweir 		Bitmap aBmp;
4196*cdf0e10cSrcweir 		*pStream >> aBmp;
4197*cdf0e10cSrcweir 		Graphic aGraphic( aBmp );
4198*cdf0e10cSrcweir 
4199*cdf0e10cSrcweir 		SbxObjectRef xRef = new SbStdPicture;
4200*cdf0e10cSrcweir 		((SbStdPicture*)(SbxObject*)xRef)->SetGraphic( aGraphic );
4201*cdf0e10cSrcweir 		rPar.Get(0)->PutObject( xRef );
4202*cdf0e10cSrcweir 	}
4203*cdf0e10cSrcweir 	delete pStream;
4204*cdf0e10cSrcweir }
4205*cdf0e10cSrcweir 
4206*cdf0e10cSrcweir RTLFUNC(SavePicture)
4207*cdf0e10cSrcweir {
4208*cdf0e10cSrcweir     (void)pBasic;
4209*cdf0e10cSrcweir     (void)bWrite;
4210*cdf0e10cSrcweir 
4211*cdf0e10cSrcweir 	rPar.Get(0)->PutEmpty();
4212*cdf0e10cSrcweir 	if( rPar.Count() != 3 )
4213*cdf0e10cSrcweir 	{
4214*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
4215*cdf0e10cSrcweir 		return;
4216*cdf0e10cSrcweir 	}
4217*cdf0e10cSrcweir 
4218*cdf0e10cSrcweir 	SbxBase* pObj = (SbxObject*)rPar.Get(1)->GetObject();
4219*cdf0e10cSrcweir 	if( pObj->IsA( TYPE( SbStdPicture ) ) )
4220*cdf0e10cSrcweir 	{
4221*cdf0e10cSrcweir 		SvFileStream aOStream( rPar.Get(2)->GetString(), STREAM_WRITE | STREAM_TRUNC );
4222*cdf0e10cSrcweir 		Graphic aGraphic = ((SbStdPicture*)pObj)->GetGraphic();
4223*cdf0e10cSrcweir 		aOStream << aGraphic;
4224*cdf0e10cSrcweir 	}
4225*cdf0e10cSrcweir }
4226*cdf0e10cSrcweir 
4227*cdf0e10cSrcweir 
4228*cdf0e10cSrcweir //-----------------------------------------------------------------------------------------
4229*cdf0e10cSrcweir 
4230*cdf0e10cSrcweir RTLFUNC(AboutStarBasic)
4231*cdf0e10cSrcweir {
4232*cdf0e10cSrcweir     (void)pBasic;
4233*cdf0e10cSrcweir     (void)bWrite;
4234*cdf0e10cSrcweir     (void)rPar;
4235*cdf0e10cSrcweir }
4236*cdf0e10cSrcweir 
4237*cdf0e10cSrcweir RTLFUNC(MsgBox)
4238*cdf0e10cSrcweir {
4239*cdf0e10cSrcweir     (void)pBasic;
4240*cdf0e10cSrcweir     (void)bWrite;
4241*cdf0e10cSrcweir 
4242*cdf0e10cSrcweir 	static const WinBits nStyleMap[] =
4243*cdf0e10cSrcweir 	{
4244*cdf0e10cSrcweir 		WB_OK,				// MB_OK
4245*cdf0e10cSrcweir 		WB_OK_CANCEL,       // MB_OKCANCEL
4246*cdf0e10cSrcweir 		WB_ABORT_RETRY_IGNORE,    // MB_ABORTRETRYIGNORE
4247*cdf0e10cSrcweir 		WB_YES_NO_CANCEL,   // MB_YESNOCANCEL
4248*cdf0e10cSrcweir 		WB_YES_NO,          // MB_YESNO
4249*cdf0e10cSrcweir 		WB_RETRY_CANCEL     // MB_RETRYCANCEL
4250*cdf0e10cSrcweir 	};
4251*cdf0e10cSrcweir 	static const sal_Int16 nButtonMap[] =
4252*cdf0e10cSrcweir 	{
4253*cdf0e10cSrcweir 		2, // #define RET_CANCEL sal_False
4254*cdf0e10cSrcweir 		1, // #define RET_OK     sal_True
4255*cdf0e10cSrcweir 		6, // #define RET_YES    2
4256*cdf0e10cSrcweir 		7, // #define RET_NO     3
4257*cdf0e10cSrcweir 		4  // #define RET_RETRY  4
4258*cdf0e10cSrcweir 	};
4259*cdf0e10cSrcweir 
4260*cdf0e10cSrcweir 
4261*cdf0e10cSrcweir 	sal_uInt16 nArgCount = (sal_uInt16)rPar.Count();
4262*cdf0e10cSrcweir 	if( nArgCount < 2 || nArgCount > 6 )
4263*cdf0e10cSrcweir 	{
4264*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
4265*cdf0e10cSrcweir 		return;
4266*cdf0e10cSrcweir 	}
4267*cdf0e10cSrcweir 	WinBits nWinBits;
4268*cdf0e10cSrcweir 	WinBits nType = 0; // MB_OK
4269*cdf0e10cSrcweir 	if( nArgCount >= 3 )
4270*cdf0e10cSrcweir 		nType = (WinBits)rPar.Get(2)->GetInteger();
4271*cdf0e10cSrcweir 	WinBits nStyle = nType;
4272*cdf0e10cSrcweir 	nStyle &= 15; // Bits 4-16 loeschen
4273*cdf0e10cSrcweir 	if( nStyle > 5 )
4274*cdf0e10cSrcweir 		nStyle = 0;
4275*cdf0e10cSrcweir 
4276*cdf0e10cSrcweir 	nWinBits = nStyleMap[ nStyle ];
4277*cdf0e10cSrcweir 
4278*cdf0e10cSrcweir 	WinBits nWinDefBits;
4279*cdf0e10cSrcweir 	nWinDefBits = (WB_DEF_OK | WB_DEF_RETRY | WB_DEF_YES);
4280*cdf0e10cSrcweir 	if( nType & 256 )
4281*cdf0e10cSrcweir 	{
4282*cdf0e10cSrcweir 		if( nStyle == 5 )
4283*cdf0e10cSrcweir 			nWinDefBits = WB_DEF_CANCEL;
4284*cdf0e10cSrcweir 		else if( nStyle == 2 )
4285*cdf0e10cSrcweir 			nWinDefBits = WB_DEF_RETRY;
4286*cdf0e10cSrcweir 		else
4287*cdf0e10cSrcweir 			nWinDefBits = (WB_DEF_CANCEL | WB_DEF_RETRY | WB_DEF_NO);
4288*cdf0e10cSrcweir 	}
4289*cdf0e10cSrcweir 	else if( nType & 512 )
4290*cdf0e10cSrcweir 	{
4291*cdf0e10cSrcweir 		if( nStyle == 2)
4292*cdf0e10cSrcweir 			nWinDefBits = WB_DEF_IGNORE;
4293*cdf0e10cSrcweir 		else
4294*cdf0e10cSrcweir 			nWinDefBits = WB_DEF_CANCEL;
4295*cdf0e10cSrcweir 	}
4296*cdf0e10cSrcweir 	else if( nStyle == 2)
4297*cdf0e10cSrcweir 		nWinDefBits = WB_DEF_CANCEL;
4298*cdf0e10cSrcweir     nWinBits |= nWinDefBits;
4299*cdf0e10cSrcweir 
4300*cdf0e10cSrcweir 	String aMsg = rPar.Get(1)->GetString();
4301*cdf0e10cSrcweir 	String aTitle;
4302*cdf0e10cSrcweir 	if( nArgCount >= 4 )
4303*cdf0e10cSrcweir 		aTitle = rPar.Get(3)->GetString();
4304*cdf0e10cSrcweir 	else
4305*cdf0e10cSrcweir 		aTitle = GetpApp()->GetAppName();
4306*cdf0e10cSrcweir 
4307*cdf0e10cSrcweir 	nType &= (16+32+64);
4308*cdf0e10cSrcweir 	MessBox* pBox = 0;
4309*cdf0e10cSrcweir 	Window* pParent = GetpApp()->GetDefDialogParent();
4310*cdf0e10cSrcweir 	switch( nType )
4311*cdf0e10cSrcweir 	{
4312*cdf0e10cSrcweir 		case 16:
4313*cdf0e10cSrcweir 			pBox = new ErrorBox( pParent, nWinBits, aMsg );
4314*cdf0e10cSrcweir 			break;
4315*cdf0e10cSrcweir 		case 32:
4316*cdf0e10cSrcweir 			pBox = new QueryBox( pParent, nWinBits, aMsg );
4317*cdf0e10cSrcweir 			break;
4318*cdf0e10cSrcweir 		case 48:
4319*cdf0e10cSrcweir 			pBox = new WarningBox( pParent, nWinBits, aMsg );
4320*cdf0e10cSrcweir 			break;
4321*cdf0e10cSrcweir 		case 64:
4322*cdf0e10cSrcweir 			pBox = new InfoBox( pParent, aMsg );
4323*cdf0e10cSrcweir 			break;
4324*cdf0e10cSrcweir 		default:
4325*cdf0e10cSrcweir 			pBox = new MessBox( pParent, nWinBits, aTitle, aMsg );
4326*cdf0e10cSrcweir 	}
4327*cdf0e10cSrcweir 	pBox->SetText( aTitle );
4328*cdf0e10cSrcweir 	sal_uInt16 nRet = (sal_uInt16)pBox->Execute();
4329*cdf0e10cSrcweir 	if( nRet == sal_True )
4330*cdf0e10cSrcweir 		nRet = 1;
4331*cdf0e10cSrcweir 
4332*cdf0e10cSrcweir 	sal_Int16 nMappedRet;
4333*cdf0e10cSrcweir 	if( nStyle == 2 )
4334*cdf0e10cSrcweir 	{
4335*cdf0e10cSrcweir 		nMappedRet = nRet;
4336*cdf0e10cSrcweir 		if( nMappedRet == 0 )
4337*cdf0e10cSrcweir 			nMappedRet = 3;	// Abort
4338*cdf0e10cSrcweir 	}
4339*cdf0e10cSrcweir 	else
4340*cdf0e10cSrcweir 		nMappedRet = nButtonMap[ nRet ];
4341*cdf0e10cSrcweir 
4342*cdf0e10cSrcweir 	rPar.Get(0)->PutInteger( nMappedRet );
4343*cdf0e10cSrcweir 	delete pBox;
4344*cdf0e10cSrcweir }
4345*cdf0e10cSrcweir 
4346*cdf0e10cSrcweir RTLFUNC(SetAttr) // JSM
4347*cdf0e10cSrcweir {
4348*cdf0e10cSrcweir     (void)pBasic;
4349*cdf0e10cSrcweir     (void)bWrite;
4350*cdf0e10cSrcweir 
4351*cdf0e10cSrcweir 	rPar.Get(0)->PutEmpty();
4352*cdf0e10cSrcweir 	if ( rPar.Count() == 3 )
4353*cdf0e10cSrcweir 	{
4354*cdf0e10cSrcweir 		String aStr = rPar.Get(1)->GetString();
4355*cdf0e10cSrcweir 		sal_Int16 nFlags = rPar.Get(2)->GetInteger();
4356*cdf0e10cSrcweir 
4357*cdf0e10cSrcweir 		// <-- UCB
4358*cdf0e10cSrcweir 		if( hasUno() )
4359*cdf0e10cSrcweir 		{
4360*cdf0e10cSrcweir 			com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess();
4361*cdf0e10cSrcweir 			if( xSFI.is() )
4362*cdf0e10cSrcweir 			{
4363*cdf0e10cSrcweir 				try
4364*cdf0e10cSrcweir 				{
4365*cdf0e10cSrcweir 					sal_Bool bReadOnly = (nFlags & 0x0001) != 0; // ATTR_READONLY
4366*cdf0e10cSrcweir 					xSFI->setReadOnly( aStr, bReadOnly );
4367*cdf0e10cSrcweir 					sal_Bool bHidden   = (nFlags & 0x0002) != 0; // ATTR_HIDDEN
4368*cdf0e10cSrcweir 					xSFI->setHidden( aStr, bHidden );
4369*cdf0e10cSrcweir 				}
4370*cdf0e10cSrcweir 				catch( Exception & )
4371*cdf0e10cSrcweir 				{
4372*cdf0e10cSrcweir 					StarBASIC::Error( ERRCODE_IO_GENERAL );
4373*cdf0e10cSrcweir 				}
4374*cdf0e10cSrcweir 			}
4375*cdf0e10cSrcweir 		}
4376*cdf0e10cSrcweir 		else
4377*cdf0e10cSrcweir 		// --> UCB
4378*cdf0e10cSrcweir 		{
4379*cdf0e10cSrcweir #ifdef _OLD_FILE_IMPL
4380*cdf0e10cSrcweir 			// #57064 Bei virtuellen URLs den Real-Path extrahieren
4381*cdf0e10cSrcweir 			DirEntry aEntry( aStr );
4382*cdf0e10cSrcweir 			String aFile = aEntry.GetFull();
4383*cdf0e10cSrcweir 			ByteString aByteFile( aFile, gsl_getSystemTextEncoding() );
4384*cdf0e10cSrcweir 	#ifdef WNT
4385*cdf0e10cSrcweir 			if (!SetFileAttributes (aByteFile.GetBuffer(),(DWORD)nFlags))
4386*cdf0e10cSrcweir 				StarBASIC::Error(SbERR_FILE_NOT_FOUND);
4387*cdf0e10cSrcweir 	#endif
4388*cdf0e10cSrcweir 	#ifdef OS2
4389*cdf0e10cSrcweir 			FILESTATUS3 aFileStatus;
4390*cdf0e10cSrcweir 			APIRET rc = DosQueryPathInfo(aByteFile.GetBuffer(),1,
4391*cdf0e10cSrcweir 										 &aFileStatus,sizeof(FILESTATUS3));
4392*cdf0e10cSrcweir 			if (!rc)
4393*cdf0e10cSrcweir 			{
4394*cdf0e10cSrcweir 				if (aFileStatus.attrFile != nFlags)
4395*cdf0e10cSrcweir 				{
4396*cdf0e10cSrcweir 					aFileStatus.attrFile = nFlags;
4397*cdf0e10cSrcweir 					rc = DosSetPathInfo(aFile.GetStr(),1,
4398*cdf0e10cSrcweir 										&aFileStatus,sizeof(FILESTATUS3),0);
4399*cdf0e10cSrcweir 					if (rc)
4400*cdf0e10cSrcweir 						StarBASIC::Error( SbERR_FILE_NOT_FOUND );
4401*cdf0e10cSrcweir 				}
4402*cdf0e10cSrcweir 			}
4403*cdf0e10cSrcweir 			else
4404*cdf0e10cSrcweir 				StarBASIC::Error( SbERR_FILE_NOT_FOUND );
4405*cdf0e10cSrcweir 	#endif
4406*cdf0e10cSrcweir #else
4407*cdf0e10cSrcweir 			// Not implemented
4408*cdf0e10cSrcweir #endif
4409*cdf0e10cSrcweir 		}
4410*cdf0e10cSrcweir 	}
4411*cdf0e10cSrcweir 	else
4412*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
4413*cdf0e10cSrcweir }
4414*cdf0e10cSrcweir 
4415*cdf0e10cSrcweir RTLFUNC(Reset)  // JSM
4416*cdf0e10cSrcweir {
4417*cdf0e10cSrcweir     (void)pBasic;
4418*cdf0e10cSrcweir     (void)bWrite;
4419*cdf0e10cSrcweir     (void)rPar;
4420*cdf0e10cSrcweir 
4421*cdf0e10cSrcweir 	SbiIoSystem* pIO = pINST->GetIoSystem();
4422*cdf0e10cSrcweir 	if (pIO)
4423*cdf0e10cSrcweir 		pIO->CloseAll();
4424*cdf0e10cSrcweir }
4425*cdf0e10cSrcweir 
4426*cdf0e10cSrcweir RTLFUNC(DumpAllObjects)
4427*cdf0e10cSrcweir {
4428*cdf0e10cSrcweir     (void)pBasic;
4429*cdf0e10cSrcweir     (void)bWrite;
4430*cdf0e10cSrcweir 
4431*cdf0e10cSrcweir 	sal_uInt16 nArgCount = (sal_uInt16)rPar.Count();
4432*cdf0e10cSrcweir 	if( nArgCount < 2 || nArgCount > 3 )
4433*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
4434*cdf0e10cSrcweir 	else if( !pBasic )
4435*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_INTERNAL_ERROR );
4436*cdf0e10cSrcweir 	else
4437*cdf0e10cSrcweir 	{
4438*cdf0e10cSrcweir 		SbxObject* p = pBasic;
4439*cdf0e10cSrcweir 		while( p->GetParent() )
4440*cdf0e10cSrcweir 			p = p->GetParent();
4441*cdf0e10cSrcweir 		SvFileStream aStrm( rPar.Get( 1 )->GetString(),
4442*cdf0e10cSrcweir 							STREAM_WRITE | STREAM_TRUNC );
4443*cdf0e10cSrcweir 		p->Dump( aStrm, rPar.Get( 2 )->GetBool() );
4444*cdf0e10cSrcweir 		aStrm.Close();
4445*cdf0e10cSrcweir 		if( aStrm.GetError() != SVSTREAM_OK )
4446*cdf0e10cSrcweir 			StarBASIC::Error( SbERR_IO_ERROR );
4447*cdf0e10cSrcweir 	}
4448*cdf0e10cSrcweir }
4449*cdf0e10cSrcweir 
4450*cdf0e10cSrcweir 
4451*cdf0e10cSrcweir RTLFUNC(FileExists)
4452*cdf0e10cSrcweir {
4453*cdf0e10cSrcweir     (void)pBasic;
4454*cdf0e10cSrcweir     (void)bWrite;
4455*cdf0e10cSrcweir 
4456*cdf0e10cSrcweir 	if ( rPar.Count() == 2 )
4457*cdf0e10cSrcweir 	{
4458*cdf0e10cSrcweir 		String aStr = rPar.Get(1)->GetString();
4459*cdf0e10cSrcweir 		sal_Bool bExists = sal_False;
4460*cdf0e10cSrcweir 
4461*cdf0e10cSrcweir 		// <-- UCB
4462*cdf0e10cSrcweir 		if( hasUno() )
4463*cdf0e10cSrcweir 		{
4464*cdf0e10cSrcweir 			com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess();
4465*cdf0e10cSrcweir 			if( xSFI.is() )
4466*cdf0e10cSrcweir 			{
4467*cdf0e10cSrcweir 				try
4468*cdf0e10cSrcweir 				{
4469*cdf0e10cSrcweir 					bExists = xSFI->exists( aStr );
4470*cdf0e10cSrcweir 				}
4471*cdf0e10cSrcweir 				catch( Exception & )
4472*cdf0e10cSrcweir 				{
4473*cdf0e10cSrcweir 					StarBASIC::Error( ERRCODE_IO_GENERAL );
4474*cdf0e10cSrcweir 				}
4475*cdf0e10cSrcweir 			}
4476*cdf0e10cSrcweir 		}
4477*cdf0e10cSrcweir 		else
4478*cdf0e10cSrcweir 		// --> UCB
4479*cdf0e10cSrcweir 		{
4480*cdf0e10cSrcweir #ifdef _OLD_FILE_IMPL
4481*cdf0e10cSrcweir 			DirEntry aEntry( aStr );
4482*cdf0e10cSrcweir 			bExists = aEntry.Exists();
4483*cdf0e10cSrcweir #else
4484*cdf0e10cSrcweir 			DirectoryItem aItem;
4485*cdf0e10cSrcweir 			FileBase::RC nRet = DirectoryItem::get( getFullPathUNC( aStr ), aItem );
4486*cdf0e10cSrcweir 			bExists = (nRet == FileBase::E_None);
4487*cdf0e10cSrcweir #endif
4488*cdf0e10cSrcweir 		}
4489*cdf0e10cSrcweir 		rPar.Get(0)->PutBool( bExists );
4490*cdf0e10cSrcweir 	}
4491*cdf0e10cSrcweir 	else
4492*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
4493*cdf0e10cSrcweir }
4494*cdf0e10cSrcweir 
4495*cdf0e10cSrcweir RTLFUNC(Partition)
4496*cdf0e10cSrcweir {
4497*cdf0e10cSrcweir     (void)pBasic;
4498*cdf0e10cSrcweir     (void)bWrite;
4499*cdf0e10cSrcweir 
4500*cdf0e10cSrcweir 	if ( rPar.Count() != 5 )
4501*cdf0e10cSrcweir 	{
4502*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
4503*cdf0e10cSrcweir 		return;
4504*cdf0e10cSrcweir 	}
4505*cdf0e10cSrcweir 
4506*cdf0e10cSrcweir 	sal_Int32 nNumber = rPar.Get(1)->GetLong();
4507*cdf0e10cSrcweir 	sal_Int32 nStart = rPar.Get(2)->GetLong();
4508*cdf0e10cSrcweir 	sal_Int32 nStop = rPar.Get(3)->GetLong();
4509*cdf0e10cSrcweir 	sal_Int32 nInterval = rPar.Get(4)->GetLong();
4510*cdf0e10cSrcweir 
4511*cdf0e10cSrcweir 	if( nStart < 0 || nStop <= nStart || nInterval < 1 )
4512*cdf0e10cSrcweir 	{
4513*cdf0e10cSrcweir 		StarBASIC::Error( SbERR_BAD_ARGUMENT );
4514*cdf0e10cSrcweir 		return;
4515*cdf0e10cSrcweir 	}
4516*cdf0e10cSrcweir 
4517*cdf0e10cSrcweir 	// the Partition function inserts leading spaces before lowervalue and uppervalue
4518*cdf0e10cSrcweir     // so that they both have the same number of characters as the string
4519*cdf0e10cSrcweir     // representation of the value (Stop + 1). This ensures that if you use the output
4520*cdf0e10cSrcweir     // of the Partition function with several values of Number, the resulting text
4521*cdf0e10cSrcweir 	// will be handled properly during any subsequent sort operation.
4522*cdf0e10cSrcweir 
4523*cdf0e10cSrcweir 	// calculate the  maximun number of characters before lowervalue and uppervalue
4524*cdf0e10cSrcweir 	::rtl::OUString aBeforeStart = ::rtl::OUString::valueOf( nStart - 1 );
4525*cdf0e10cSrcweir 	::rtl::OUString aAfterStop = ::rtl::OUString::valueOf( nStop + 1 );
4526*cdf0e10cSrcweir 	sal_Int32 nLen1 = aBeforeStart.getLength();
4527*cdf0e10cSrcweir 	sal_Int32 nLen2 = aAfterStop.getLength();
4528*cdf0e10cSrcweir 	sal_Int32 nLen = nLen1 >= nLen2 ? nLen1:nLen2;
4529*cdf0e10cSrcweir 
4530*cdf0e10cSrcweir 	::rtl::OUStringBuffer aRetStr( nLen * 2 + 1);
4531*cdf0e10cSrcweir 	::rtl::OUString aLowerValue;
4532*cdf0e10cSrcweir 	::rtl::OUString aUpperValue;
4533*cdf0e10cSrcweir 	if( nNumber < nStart )
4534*cdf0e10cSrcweir 	{
4535*cdf0e10cSrcweir 		aUpperValue = aBeforeStart;
4536*cdf0e10cSrcweir 	}
4537*cdf0e10cSrcweir 	else if( nNumber > nStop )
4538*cdf0e10cSrcweir 	{
4539*cdf0e10cSrcweir 		aLowerValue = aAfterStop;
4540*cdf0e10cSrcweir 	}
4541*cdf0e10cSrcweir 	else
4542*cdf0e10cSrcweir 	{
4543*cdf0e10cSrcweir 		sal_Int32 nLowerValue = nNumber;
4544*cdf0e10cSrcweir 		sal_Int32 nUpperValue = nLowerValue;
4545*cdf0e10cSrcweir 		if( nInterval > 1 )
4546*cdf0e10cSrcweir 		{
4547*cdf0e10cSrcweir 			nLowerValue = ((( nNumber - nStart ) / nInterval ) * nInterval ) + nStart;
4548*cdf0e10cSrcweir 			nUpperValue = nLowerValue + nInterval - 1;
4549*cdf0e10cSrcweir 		}
4550*cdf0e10cSrcweir 
4551*cdf0e10cSrcweir 		aLowerValue = ::rtl::OUString::valueOf( nLowerValue );
4552*cdf0e10cSrcweir 		aUpperValue = ::rtl::OUString::valueOf( nUpperValue );
4553*cdf0e10cSrcweir 	}
4554*cdf0e10cSrcweir 
4555*cdf0e10cSrcweir 	nLen1 = aLowerValue.getLength();
4556*cdf0e10cSrcweir 	nLen2 = aUpperValue.getLength();
4557*cdf0e10cSrcweir 
4558*cdf0e10cSrcweir 	if( nLen > nLen1 )
4559*cdf0e10cSrcweir 	{
4560*cdf0e10cSrcweir 		// appending the leading spaces for the lowervalue
4561*cdf0e10cSrcweir 		for ( sal_Int32 i= (nLen - nLen1) ; i > 0; --i )
4562*cdf0e10cSrcweir 			aRetStr.appendAscii(" ");
4563*cdf0e10cSrcweir 	}
4564*cdf0e10cSrcweir 	aRetStr.append( aLowerValue ).appendAscii(":");
4565*cdf0e10cSrcweir 	if( nLen > nLen2 )
4566*cdf0e10cSrcweir 	{
4567*cdf0e10cSrcweir 		// appending the leading spaces for the uppervalue
4568*cdf0e10cSrcweir 		for ( sal_Int32 i= (nLen - nLen2) ; i > 0; --i )
4569*cdf0e10cSrcweir 			aRetStr.appendAscii(" ");
4570*cdf0e10cSrcweir 	}
4571*cdf0e10cSrcweir 	aRetStr.append( aUpperValue );
4572*cdf0e10cSrcweir 	rPar.Get(0)->PutString( String(aRetStr.makeStringAndClear()) );
4573*cdf0e10cSrcweir }
4574