summaryrefslogtreecommitdiff
path: root/basic/source/runtime/methods.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'basic/source/runtime/methods.cxx')
-rw-r--r--basic/source/runtime/methods.cxx3228
1 files changed, 3228 insertions, 0 deletions
diff --git a/basic/source/runtime/methods.cxx b/basic/source/runtime/methods.cxx
new file mode 100644
index 000000000000..e3a47cba275c
--- /dev/null
+++ b/basic/source/runtime/methods.cxx
@@ -0,0 +1,3228 @@
+/*************************************************************************
+ *
+ * $RCSfile: methods.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:12:11 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+
+#ifndef _DATE_HXX //autogen
+#include <tools/date.hxx>
+#endif
+#ifndef _SBXVAR_HXX
+#include <svtools/sbxvar.hxx>
+#endif
+#ifndef _FSYS_HXX //autogen
+#include <tools/fsys.hxx>
+#endif
+#ifndef _INTN_HXX //autogen
+#include <tools/intn.hxx>
+#endif
+#ifndef _VOS_PROCESS_HXX
+#include <vos/process.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX //autogen
+#include <vcl/svapp.hxx>
+#endif
+#ifndef _SV_SOUND_HXX //autogen
+#include <vcl/sound.hxx>
+#endif
+#ifndef _SV_WINTYPES_HXX //autogen
+#include <vcl/wintypes.hxx>
+#endif
+#ifndef _SV_MSGBOX_HXX //autogen
+#include <vcl/msgbox.hxx>
+#endif
+#ifndef _SBXCLASS_HXX //autogen
+#include <svtools/sbx.hxx>
+#endif
+#ifndef _ZFORLIST_HXX //autogen
+#include <svtools/zforlist.hxx>
+#endif
+#ifndef _TOOLS_SOLMATH_HXX //autogen wg. SolarMath
+#include <tools/solmath.hxx>
+#endif
+#include <tools/urlobj.hxx>
+#include <osl/file.hxx>
+
+#ifdef OS2
+#define INCL_WINWINDOWMGR
+#define INCL_DOS
+#endif
+
+#if defined (WNT)
+#ifndef _SVWIN_H
+#include <tools/svwin.h>
+#endif
+#endif
+#if defined (OS2)
+#ifndef _SVPM_H
+#include <tools/svpm.h>
+#endif
+#endif
+
+#pragma hdrstop
+#include "runtime.hxx"
+
+#ifdef _USE_UNO
+#include <unotools/processfactory.hxx>
+
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/util/DateTime.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/io/XStream.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+
+using namespace utl;
+using namespace rtl;
+using namespace osl;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::ucb;
+using namespace com::sun::star::io;
+
+#endif /* _USE_UNO */
+
+#include "stdobj.hxx"
+#include "stdobj1.hxx"
+#include "rtlproto.hxx"
+#include "basrid.hxx"
+#include "sb.hrc"
+#ifndef _SBIOSYS_HXX
+#include "iosys.hxx"
+#endif
+#ifndef _DDECTRL_HXX
+#include "ddectrl.hxx"
+#endif
+#include <sbintern.hxx>
+
+#include <stl/list>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#if defined (WIN) || defined (WNT) || defined (OS2)
+#include <direct.h> // _getdcwd get current work directory, _chdrive
+#endif
+
+#ifdef WIN
+#include <dos.h> // _dos_getfileattr
+#include <errno.h>
+#endif
+
+#ifdef UNX
+#include <errno.h>
+#include <unistd.h>
+#endif
+
+#ifdef WNT
+#include <io.h>
+#endif
+
+#ifdef MAC
+#include <mac_start.h>
+
+#ifndef __FILES__
+ #include <Files.h>
+#endif
+
+#ifndef __ERRORS__
+ #include <Errors.h>
+#endif
+
+#include <MAC_TOOLS.hxx>
+#include <mac_end.h>
+#endif
+
+//#include <numbers.hxx>
+
+#include "segmentc.hxx"
+#pragma SW_SEGMENT_CLASS( SBRUNTIME, SBRUNTIME_CODE )
+
+
+#if defined (OS2) && defined (__BORLANDC__)
+#pragma option -w-par
+#endif
+
+static void FilterWhiteSpace( String& rStr )
+{
+ rStr.EraseAllChars( ' ' );
+ rStr.EraseAllChars( '\t' );
+ rStr.EraseAllChars( '\n' );
+ rStr.EraseAllChars( '\r' );
+}
+
+static long GetDayDiff( const Date& rDate )
+{
+ Date aRefDate( 1,1,1900 );
+ long nDiffDays;
+ if ( aRefDate > rDate )
+ {
+ nDiffDays = (long)(aRefDate - rDate);
+ nDiffDays *= -1;
+ }
+ else
+ nDiffDays = (long)(rDate - aRefDate);
+ nDiffDays += 2; // Anpassung VisualBasic: 1.Jan.1900 == 2
+ return nDiffDays;
+}
+
+
+//*** UCB file access ***
+// Converts possibly relative paths to absolute paths
+// according to the setting done by ChDir/ChDrive
+// (Implemented in methods.cxx)
+String getFullPath( const String& aRelPath )
+{
+ // TODO: Use CurDir to build full path
+ // First step: Return given path unchanged
+ return aRelPath;
+}
+
+// Sets (virtual) current path for UCB file access
+void implChDir( const String& aDir )
+{
+ // TODO
+}
+
+// Sets (virtual) current drive for UCB file access
+void implChDrive( const String& aDrive )
+{
+ // TODO
+}
+
+// Returns (virtual) current path for UCB file access
+String implGetCurDir( void )
+{
+ String aRetStr;
+
+ return aRetStr;
+}
+
+// TODO: -> SbiGlobals
+static Reference< XSimpleFileAccess > getFileAccess( void )
+{
+ static Reference< XSimpleFileAccess > xSFI;
+ if( !xSFI.is() )
+ {
+ Reference< XMultiServiceFactory > xSMgr = getProcessServiceFactory();
+ if( xSMgr.is() )
+ {
+ xSFI = Reference< XSimpleFileAccess >( xSMgr->createInstance
+ ( OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY );
+ }
+ }
+ return xSFI;
+}
+
+
+
+
+// Properties und Methoden legen beim Get (bPut = FALSE) den Returnwert
+// im Element 0 des Argv ab; beim Put (bPut = TRUE) wird der Wert aus
+// Element 0 gespeichert.
+
+// CreateObject( class )
+
+RTLFUNC(CreateObject)
+{
+ String aClass( rPar.Get( 1 )->GetString() );
+ SbxObjectRef p = SbxBase::CreateObject( aClass );
+ if( !p )
+ StarBASIC::Error( SbERR_CANNOT_LOAD );
+ else
+ {
+ // Convenience: BASIC als Parent eintragen
+ p->SetParent( pBasic );
+ rPar.Get( 0 )->PutObject( p );
+ }
+}
+
+// Error( n )
+
+RTLFUNC(Error)
+{
+ if( !pBasic )
+ StarBASIC::Error( SbERR_INTERNAL_ERROR );
+ else
+ {
+ String aErrorMsg;
+ SbError nErr = 0L;
+ if( rPar.Count() == 1 )
+ {
+ nErr = StarBASIC::GetErr();
+ aErrorMsg = StarBASIC::GetErrorMsg();
+ }
+ else
+ {
+ INT32 nCode = rPar.Get( 1 )->GetLong();
+ if( nCode > 65535L )
+ StarBASIC::Error( SbERR_CONVERSION );
+ else
+ nErr = StarBASIC::GetSfxFromVBError( (USHORT)nCode );
+ }
+ pBasic->MakeErrorText( nErr, aErrorMsg );
+ rPar.Get( 0 )->PutString( pBasic->GetErrorText() );
+ }
+}
+
+// Sinus
+
+RTLFUNC(Sin)
+{
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ SbxVariableRef pArg = rPar.Get( 1 );
+ rPar.Get( 0 )->PutDouble( sin( pArg->GetDouble() ) );
+ }
+}
+
+// Cosinus
+
+RTLFUNC(Cos)
+{
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ SbxVariableRef pArg = rPar.Get( 1 );
+ rPar.Get( 0 )->PutDouble( cos( pArg->GetDouble() ) );
+ }
+}
+
+// Atn
+
+RTLFUNC(Atn)
+{
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ SbxVariableRef pArg = rPar.Get( 1 );
+ rPar.Get( 0 )->PutDouble( atan( pArg->GetDouble() ) );
+ }
+}
+
+
+
+RTLFUNC(Abs)
+{
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ SbxVariableRef pArg = rPar.Get( 1 );
+ rPar.Get( 0 )->PutDouble( fabs( pArg->GetDouble() ) );
+ }
+}
+
+
+RTLFUNC(Asc)
+{
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ SbxVariableRef pArg = rPar.Get( 1 );
+ String aStr( pArg->GetString() );
+ if ( aStr.Len() == 0 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ rPar.Get(0)->PutEmpty();
+ }
+ else
+ {
+ sal_Unicode aCh = aStr.GetBuffer()[0];
+ rPar.Get(0)->PutInteger( (INT16)aCh );
+ }
+ }
+}
+
+RTLFUNC(Chr)
+{
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ SbxVariableRef pArg = rPar.Get( 1 );
+ char aCh = (char) pArg->GetInteger();
+ String aStr;
+ aStr = aCh;
+ rPar.Get(0)->PutString( aStr );
+ }
+}
+
+
+#ifdef UNX
+#define _MAX_PATH 260
+#define _PATH_INCR 250
+#endif
+
+RTLFUNC(CurDir)
+{
+ // #57064 Obwohl diese Funktion nicht mit DirEntry arbeitet, ist sie von
+ // der Anpassung an virtuelle URLs nich betroffen, da bei Nutzung der
+ // DirEntry-Funktionalitaet keine Moeglichkeit besteht, das aktuelle so
+ // zu ermitteln, dass eine virtuelle URL geliefert werden koennte.
+
+// rPar.Get(0)->PutEmpty();
+#if defined (WIN) || defined (WNT) || (defined (OS2) && !defined( WTC ))
+ int nCurDir = 0; // Current dir // JSM
+ if ( rPar.Count() == 2 )
+ {
+ String aDrive = rPar.Get(1)->GetString();
+ if ( aDrive.Len() != 1 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ else
+ {
+ nCurDir = (int)aDrive.GetBuffer()[0];
+ if ( !isalpha( nCurDir ) )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ else
+ nCurDir -= ( 'A' - 1 );
+ }
+ }
+ char* pBuffer = new char[ _MAX_PATH ];
+#ifdef MTW
+ int old = _getdrive();
+ _chdrive(nCurDir);
+
+ if ( getcwd( pBuffer, _MAX_PATH ) != 0 )
+ rPar.Get(0)->PutString( String::CreateFromAscii( pBuffer ) );
+ else
+ StarBASIC::Error( SbERR_NO_DEVICE );
+ delete pBuffer;
+ _chdrive(old);
+#else
+#ifdef OS2
+ if( !nCurDir )
+ nCurDir = _getdrive();
+#endif
+ if ( _getdcwd( nCurDir, pBuffer, _MAX_PATH ) != 0 )
+ rPar.Get(0)->PutString( String::CreateFromAscii( pBuffer ) );
+ else
+ StarBASIC::Error( SbERR_NO_DEVICE );
+ delete pBuffer;
+#endif
+
+#elif defined MAC
+
+ Str255 aBuffer;
+ FSSpec aFileSpec; // Pseudofile
+ String aPar1;
+ OSErr nErr;
+
+ // Erstmal aktuelle Pfad bestimmen
+ nErr = FSMakeFSSpec(0,0,"\p:X",&aFileSpec);
+
+ PathNameFromDirID( aFileSpec.parID,aFileSpec.vRefNum, (char*) aBuffer);
+ String aPath((char*) &aBuffer[1],aBuffer[0]);
+
+ if ( rPar.Count() == 2 )
+ {
+ aPar1 = rPar.Get(1)->GetString();
+
+ // Wen kein ':' drin ist dann haengen wir (netterweise) einen an
+ if (aPar1.Search(':') == STRING_NOTFOUND)
+ aPar1 += ':';
+ USHORT nFirstColon = aPar1.Search(':');
+ if (!aPar1.Len() ||
+ nFirstColon != (aPar1.Len() - 1))
+ // Kein ':' am Ende oder mehr als ein ':' oder leerer String
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ // Is Param1 eventuelle das Volume des aktuellen Pfades ?
+ USHORT nMatchPoint = aPath.Match(aPar1);
+ if (nMatchPoint != (nFirstColon + 1))
+ {
+ String aPseudoFile(aPar1);
+ aPseudoFile += 'X'; // Pseudodatei
+
+ nErr = FSMakeFSSpec(0,0,aPseudoFile.GetPascalStr(),&aFileSpec);
+
+ if(nErr == nsvErr)
+ {
+ StarBASIC::Error( SbERR_NO_DEVICE );
+ return;
+ }
+ aPath = aPar1;
+ }
+ }
+
+ rPar.Get(0)->PutString(aPath);
+
+#elif defined( UNX )
+
+ int nSize = _PATH_INCR;
+ char* pMem;
+ while( TRUE )
+ {
+ pMem = new char[nSize];
+ if( !pMem )
+ {
+ StarBASIC::Error( SbERR_NO_MEMORY );
+ return;
+ }
+ if( getcwd( pMem, nSize-1 ) != NULL )
+ {
+ rPar.Get(0)->PutString( String::CreateFromAscii(pMem) );
+ delete pMem;
+ return;
+ }
+ if( errno != ERANGE )
+ {
+ StarBASIC::Error( SbERR_INTERNAL_ERROR );
+ delete pMem;
+ return;
+ }
+ delete pMem;
+ nSize += _PATH_INCR;
+ };
+
+#endif
+}
+
+RTLFUNC(ChDir) // JSM
+{
+ rPar.Get(0)->PutEmpty();
+ if (rPar.Count() == 2)
+ {
+ String aPath = rPar.Get(1)->GetString();
+ BOOL bError = FALSE;
+#ifdef WNT
+ // #55997 Laut MI hilft es bei File-URLs einen DirEntry zwischenzuschalten
+ // #40996 Harmoniert bei Verwendung der WIN32-Funktion nicht mit getdir
+ DirEntry aEntry( aPath );
+ ByteString aFullPath( aEntry.GetFull(), gsl_getSystemTextEncoding() );
+ if( chdir( aFullPath.GetBuffer()) )
+ bError = TRUE;
+#else
+ if (!DirEntry(aPath).SetCWD())
+ bError = TRUE;
+#endif
+ if( bError )
+ StarBASIC::Error( SbERR_PATH_NOT_FOUND );
+ }
+ else
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+}
+
+RTLFUNC(ChDrive) // JSM
+{
+ rPar.Get(0)->PutEmpty();
+ if (rPar.Count() == 2)
+ {
+ // Keine Laufwerke in Unix
+#ifndef UNX
+ String aPar1 = rPar.Get(1)->GetString();
+
+#if defined (WIN) || defined (WNT) || (defined (OS2) && !defined (WTC))
+ if (aPar1.Len() > 0)
+ {
+ int nCurDrive = (int)aPar1.GetBuffer()[0]; ;
+ if ( !isalpha( nCurDrive ) )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ else
+ nCurDrive -= ( 'A' - 1 );
+ if (_chdrive(nCurDrive))
+ StarBASIC::Error( SbERR_NO_DEVICE );
+ }
+#elif defined MAC
+ // Wen kein ':' drin ist dann haengen wir (netterweise) einen an
+ if (aPar1.Search(':') == STRING_NOTFOUND)
+ aPar1 += ':';
+ if (!aPar1.Len() ||
+ aPar1.Search(':') != (aPar1.Len() - 1))
+ // Kein ':' am Ende oder mehr als ein ':' oder leerer String
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ DirEntry aDrive(aPar1);
+ if (aDrive.SetCWD())
+ return;
+ else
+ StarBASIC::Error( SbERR_NO_DEVICE );
+#endif
+
+#endif
+ // #ifndef UNX
+ }
+ else
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+}
+
+
+// Implementation of StepRENAME with UCB
+void implStepRenameUCB( const String& aSource, const String& aDest )
+{
+ Reference< XSimpleFileAccess > xSFI = getFileAccess();
+ if( xSFI.is() )
+ {
+ try
+ {
+ xSFI->move( getFullPath( aSource ), getFullPath( aDest ) );
+ }
+ catch( Exception & )
+ {
+ StarBASIC::Error( ERRCODE_IO_GENERAL );
+ }
+ }
+}
+
+RTLFUNC(FileCopy) // JSM
+{
+ rPar.Get(0)->PutEmpty();
+ if (rPar.Count() == 3)
+ {
+ String aSource = rPar.Get(1)->GetString();
+ String aDest = rPar.Get(2)->GetString();
+ // <-- UCB
+ if( hasUno() )
+ {
+ Reference< XSimpleFileAccess > xSFI = getFileAccess();
+ if( xSFI.is() )
+ {
+ try
+ {
+ xSFI->copy( getFullPath( aSource ), getFullPath( aDest ) );
+ }
+ catch( Exception & )
+ {
+ StarBASIC::Error( ERRCODE_IO_GENERAL );
+ }
+ }
+ }
+ else
+ // --> UCB
+ {
+ DirEntry aSourceDirEntry(aSource);
+ if (aSourceDirEntry.Exists())
+ {
+ if (aSourceDirEntry.CopyTo(DirEntry(aDest),FSYS_ACTION_COPYFILE) != FSYS_ERR_OK)
+ StarBASIC::Error( SbERR_PATH_NOT_FOUND );
+ }
+ else
+ StarBASIC::Error( SbERR_PATH_NOT_FOUND );
+ }
+ }
+ else
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+}
+
+RTLFUNC(Kill) // JSM
+{
+ rPar.Get(0)->PutEmpty();
+ if (rPar.Count() == 2)
+ {
+ String aFileSpec = rPar.Get(1)->GetString();
+
+ // <-- UCB
+ if( hasUno() )
+ {
+ Reference< XSimpleFileAccess > xSFI = getFileAccess();
+ if( xSFI.is() )
+ {
+ try
+ {
+ xSFI->kill( getFullPath( aFileSpec ) );
+ }
+ catch( Exception & )
+ {
+ StarBASIC::Error( ERRCODE_IO_GENERAL );
+ }
+ }
+ }
+ else
+ // --> UCB
+ {
+ if(DirEntry(aFileSpec).Kill() != FSYS_ERR_OK)
+ StarBASIC::Error( SbERR_PATH_NOT_FOUND );
+ }
+ }
+ else
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+}
+
+RTLFUNC(MkDir) // JSM
+{
+ rPar.Get(0)->PutEmpty();
+ if (rPar.Count() == 2)
+ {
+ String aPath = rPar.Get(1)->GetString();
+
+ // <-- UCB
+ if( hasUno() )
+ {
+ Reference< XSimpleFileAccess > xSFI = getFileAccess();
+ if( xSFI.is() )
+ {
+ try
+ {
+ xSFI->createFolder( getFullPath( aPath ) );
+ }
+ catch( Exception & )
+ {
+ StarBASIC::Error( ERRCODE_IO_GENERAL );
+ }
+ }
+ }
+ else
+ // --> UCB
+ {
+ if (!DirEntry(aPath).MakeDir())
+ StarBASIC::Error( SbERR_PATH_NOT_FOUND );
+ }
+ }
+ else
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+}
+
+RTLFUNC(RmDir) // JSM
+{
+ rPar.Get(0)->PutEmpty();
+ if (rPar.Count() == 2)
+ {
+ String aPath = rPar.Get(1)->GetString();
+ // <-- UCB
+ if( hasUno() )
+ {
+ Reference< XSimpleFileAccess > xSFI = getFileAccess();
+ if( xSFI.is() )
+ {
+ try
+ {
+ xSFI->kill( getFullPath( aPath ) );
+ }
+ catch( Exception & )
+ {
+ StarBASIC::Error( ERRCODE_IO_GENERAL );
+ }
+ }
+ }
+ else
+ // --> UCB
+ {
+ DirEntry aDirEntry(aPath);
+ if (aDirEntry.Kill() != FSYS_ERR_OK)
+ StarBASIC::Error( SbERR_PATH_NOT_FOUND );
+ }
+ }
+ else
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+}
+
+RTLFUNC(SendKeys) // JSM
+{
+ rPar.Get(0)->PutEmpty();
+ StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
+}
+
+RTLFUNC(Exp)
+{
+ ULONG nArgCount = rPar.Count();
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ double aDouble = rPar.Get( 1 )->GetDouble();
+ aDouble = exp( aDouble );
+ rPar.Get( 0 )->PutDouble( aDouble );
+ }
+}
+
+RTLFUNC(FileLen)
+{
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ SbxVariableRef pArg = rPar.Get( 1 );
+ String aStr( pArg->GetString() );
+ INT32 nLen = 0;
+ // <-- UCB
+ if( hasUno() )
+ {
+ Reference< XSimpleFileAccess > xSFI = getFileAccess();
+ if( xSFI.is() )
+ {
+ try
+ {
+ nLen = xSFI->getSize( getFullPath( aStr ) );
+ }
+ catch( Exception & )
+ {
+ StarBASIC::Error( ERRCODE_IO_GENERAL );
+ }
+ }
+ }
+ else
+ // --> UCB
+ {
+ FileStat aStat = DirEntry( aStr );
+ nLen = aStat.GetSize();
+ }
+ rPar.Get(0)->PutLong( (long)nLen );
+ }
+}
+
+
+RTLFUNC(Hex)
+{
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ char aBuffer[16];
+ SbxVariableRef pArg = rPar.Get( 1 );
+ if ( pArg->IsInteger() )
+ sprintf( aBuffer,"%X", pArg->GetInteger() );
+ else
+ sprintf( aBuffer,"%lX", pArg->GetLong() );
+ rPar.Get(0)->PutString( String::CreateFromAscii( aBuffer ) );
+ }
+}
+
+// InStr( [start],string,string,[compare] )
+
+RTLFUNC(InStr)
+{
+ ULONG nArgCount = rPar.Count()-1;
+ if ( nArgCount < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ USHORT nStartPos = 1;
+
+ USHORT nFirstStringPos = 1;
+ if ( nArgCount >= 3 )
+ {
+ nStartPos = (USHORT)(rPar.Get(1)->GetInteger());
+ if ( nStartPos == 0 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ nStartPos = 1;
+ }
+ nFirstStringPos++;
+ }
+ int bNotCaseSensitive = 1; // wird noch nicht ausgewertet
+ if ( nArgCount == 4 )
+ bNotCaseSensitive = rPar.Get(4)->GetInteger();
+
+ USHORT nPos;
+
+ if( !bNotCaseSensitive )
+ {
+ const String& rStr1 = rPar.Get(nFirstStringPos)->GetString();
+ const String& rToken = rPar.Get(nFirstStringPos+1)->GetString();
+
+ nPos = rStr1.Search( rToken, nStartPos-1 );
+ if ( nPos == STRING_NOTFOUND )
+ nPos = 0;
+ else
+ nPos++;
+ }
+ else
+ {
+ String aStr1 = rPar.Get(nFirstStringPos)->GetString();
+ String aToken = rPar.Get(nFirstStringPos+1)->GetString();
+
+ aStr1.ToUpperAscii();
+ aToken.ToUpperAscii();
+
+ nPos = aStr1.Search( aToken, nStartPos-1 );
+ if ( nPos == STRING_NOTFOUND )
+ nPos = 0;
+ else
+ nPos++;
+ }
+ rPar.Get(0)->PutInteger( (int)nPos );
+ }
+}
+
+
+/*
+ Int( 2.8 ) = 2.0
+ Int( -2.8 ) = -3.0
+ Fix( 2.8 ) = 2.0
+ Fix( -2.8 ) = -2.0 <- !!
+*/
+
+RTLFUNC(Int)
+{
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ SbxVariableRef pArg = rPar.Get( 1 );
+ double aDouble= pArg->GetDouble();
+ /*
+ floor( 2.8 ) = 2.0
+ floor( -2.8 ) = -3.0
+ */
+ aDouble = floor( aDouble );
+ rPar.Get(0)->PutDouble( aDouble );
+ }
+}
+
+
+
+RTLFUNC(Fix)
+{
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ SbxVariableRef pArg = rPar.Get( 1 );
+ double aDouble = pArg->GetDouble();
+ if ( aDouble >= 0.0 )
+ aDouble = floor( aDouble );
+ else
+ aDouble = ceil( aDouble );
+ rPar.Get(0)->PutDouble( aDouble );
+ }
+}
+
+
+RTLFUNC(LCase)
+{
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ const International& rInt = GetpApp()->GetAppInternational();
+ String aStr( rPar.Get(1)->GetString() );
+ rInt.ToLower( aStr );
+ rPar.Get(0)->PutString( aStr );
+ }
+}
+
+RTLFUNC(Left)
+{
+ ULONG nArgCount = rPar.Count();
+ if ( rPar.Count() < 3 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ String aStr( rPar.Get(1)->GetString() );
+ short nCount = (USHORT)( rPar.Get(2)->GetLong() );
+ if ( nCount < 0 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ aStr.Erase( (USHORT)nCount );
+ rPar.Get(0)->PutString( aStr );
+ }
+ }
+}
+
+RTLFUNC(Log)
+{
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ double aArg = rPar.Get(1)->GetDouble();
+ if ( aArg > 0 )
+ rPar.Get( 0 )->PutDouble( log( aArg ));
+ else
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ }
+}
+
+RTLFUNC(LTrim)
+{
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ String aStr( rPar.Get(1)->GetString() );
+ aStr.EraseLeadingChars();
+ rPar.Get(0)->PutString( aStr );
+ }
+}
+
+
+// Mid( String, nStart, nLength )
+
+RTLFUNC(Mid)
+{
+ ULONG nArgCount = rPar.Count()-1;
+ if ( nArgCount < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ // #23178: Funktionalitaet von Mid$ als Anweisung nachbilden, indem
+ // als weiterer (4.) Parameter ein Ersetzungsstring aufgenommen wird.
+ // Anders als im Original kann in dieser Variante der 3. Parameter
+ // nLength nicht weggelassen werden. Ist ueber bWrite schon vorgesehen.
+ if( nArgCount == 4 )
+ bWrite = TRUE;
+
+ String aArgStr = rPar.Get(1)->GetString();
+ USHORT nStartPos = (USHORT)(rPar.Get(2)->GetLong() );
+ if ( nStartPos == 0 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ nStartPos--;
+ USHORT nLen = 0xffff;
+ if ( nArgCount == 3 || bWrite )
+ nLen = (USHORT)(rPar.Get(3)->GetLong() );
+ String aResultStr;
+ if ( bWrite )
+ {
+ aResultStr = aArgStr;
+ aResultStr.Erase( nStartPos, nLen );
+ aResultStr.Insert(rPar.Get(4)->GetString(),0,nLen,nStartPos);
+ rPar.Get(1)->PutString( aResultStr );
+ }
+ else
+ {
+ aResultStr = aArgStr.Copy( nStartPos, nLen );
+ rPar.Get(0)->PutString( aResultStr );
+ }
+ }
+ }
+}
+
+RTLFUNC(Oct)
+{
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ char aBuffer[16];
+ SbxVariableRef pArg = rPar.Get( 1 );
+ if ( pArg->IsInteger() )
+ sprintf( aBuffer,"%o", pArg->GetInteger() );
+ else
+ sprintf( aBuffer,"%lo", pArg->GetLong() );
+ rPar.Get(0)->PutString( String::CreateFromAscii( aBuffer ) );
+ }
+}
+
+RTLFUNC(Right)
+{
+ ULONG nArgCount = rPar.Count();
+ if ( rPar.Count() < 3 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ const String& rStr = rPar.Get(1)->GetString();
+ USHORT nResultLen = (USHORT)(rPar.Get(2)->GetLong() );
+ USHORT nStrLen = rStr.Len();
+ if ( nResultLen > nStrLen )
+ nResultLen = nStrLen;
+ String aResultStr = rStr.Copy( nStrLen-nResultLen );
+ rPar.Get(0)->PutString( aResultStr );
+ }
+}
+
+RTLFUNC(RTrim)
+{
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ String aStr( rPar.Get(1)->GetString() );
+ aStr.EraseTrailingChars();
+ rPar.Get(0)->PutString( aStr );
+ }
+}
+
+RTLFUNC(Sgn)
+{
+ ULONG nArgCount = rPar.Count();
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ double aDouble = rPar.Get(1)->GetDouble();
+ INT16 nResult = 0;
+ if ( aDouble > 0 )
+ nResult = 1;
+ else if ( aDouble < 0 )
+ nResult = -1;
+ rPar.Get(0)->PutInteger( nResult );
+ }
+}
+
+RTLFUNC(Space)
+{
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ String aStr;
+ aStr.Fill( (USHORT)(rPar.Get(1)->GetLong() ));
+ rPar.Get(0)->PutString( aStr );
+ }
+}
+
+RTLFUNC(Spc)
+{
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ String aStr;
+ aStr.Fill( (USHORT)(rPar.Get(1)->GetLong() ));
+ rPar.Get(0)->PutString( aStr );
+ }
+}
+
+RTLFUNC(Sqr)
+{
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ double aDouble = rPar.Get(1)->GetDouble();
+ if ( aDouble >= 0 )
+ rPar.Get(0)->PutDouble( sqrt( aDouble ));
+ else
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ }
+}
+
+RTLFUNC(Str)
+{
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ String aStr;
+ rPar.Get( 1 )->Format( aStr );
+ // Numbers start with a space
+ if( rPar.Get( 1 )->IsNumericRTL() )
+ aStr.Insert( ' ', 0 );
+ // Kommas durch Punkte ersetzen, damits symmetrisch zu Val ist!
+ aStr.SearchAndReplace( ',', '.' );
+ rPar.Get(0)->PutString( aStr );
+ }
+}
+
+RTLFUNC(StrComp)
+{
+
+ if ( rPar.Count() < 3 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ rPar.Get(0)->PutEmpty();
+ return;
+ }
+ const String& rStr1 = rPar.Get(1)->GetString();
+ const String& rStr2 = rPar.Get(2)->GetString();
+ INT16 nNotCaseSensitive = TRUE;
+ if ( rPar.Count() == 4 )
+ nNotCaseSensitive = rPar.Get(3)->GetInteger();
+
+ const International& aInternational = GetpApp()->GetAppInternational();
+ StringCompare aResult;
+ if ( !nNotCaseSensitive )
+ aResult = aInternational.Compare( rStr1, rStr2 );
+ else
+ aResult = rStr1.CompareTo( rStr2 );
+ int nRetValue = 0;
+ if ( aResult == COMPARE_LESS )
+ nRetValue = -1;
+ else if ( aResult == COMPARE_GREATER )
+ nRetValue = 1;
+ rPar.Get(0)->PutInteger( nRetValue );
+}
+
+RTLFUNC(String)
+{
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ String aStr;
+ sal_Unicode aFiller;
+ USHORT nCount = (USHORT)(rPar.Get(1)->GetLong());
+ if( rPar.Get(2)->GetType() == SbxINTEGER )
+ aFiller = (char)rPar.Get(2)->GetInteger();
+ else
+ {
+ const String& rStr = rPar.Get(2)->GetString();
+ aFiller = rStr.GetBuffer()[0];
+ }
+ aStr.Fill( nCount, aFiller );
+ rPar.Get(0)->PutString( aStr );
+ }
+}
+
+RTLFUNC(Tan)
+{
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ SbxVariableRef pArg = rPar.Get( 1 );
+ rPar.Get( 0 )->PutDouble( tan( pArg->GetDouble() ) );
+ }
+}
+
+RTLFUNC(UCase)
+{
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ const International& rInt = GetpApp()->GetAppInternational();
+ String aStr( rPar.Get(1)->GetString() );
+ rInt.ToUpper( aStr );
+ rPar.Get(0)->PutString( aStr );
+ }
+}
+
+
+RTLFUNC(Val)
+{
+ static International aEnglischIntn( LANGUAGE_ENGLISH_US, LANGUAGE_ENGLISH_US );
+
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ double nResult;
+ char* pEndPtr;
+
+ String aStr( rPar.Get(1)->GetString() );
+// lt. Mikkysoft bei Kommas abbrechen!
+// for( USHORT n=0; n < aStr.Len(); n++ )
+// if( aStr[n] == ',' ) aStr[n] = '.';
+
+ FilterWhiteSpace( aStr );
+ if ( aStr.GetBuffer()[0] == '&' && aStr.Len() > 1 )
+ {
+ int nRadix = 10;
+ char aChar = aStr.GetBuffer()[1];
+ if ( aChar == 'h' || aChar == 'H' )
+ nRadix = 16;
+ else if ( aChar == 'o' || aChar == 'O' )
+ nRadix = 8;
+ if ( nRadix != 10 )
+ {
+ ByteString aByteStr( aStr, gsl_getSystemTextEncoding() );
+ INT16 nlResult = (INT16)strtol( aByteStr.GetBuffer()+2, &pEndPtr, nRadix);
+ nResult = (double)nlResult;
+ }
+ }
+ else
+ {
+ // #57844 Lokalisierte Funktion benutzen
+ int nErrno;
+ nResult = SolarMath::StringToDouble( aStr.GetBuffer(), aEnglischIntn, nErrno );
+ // ATL: nResult = strtod( aStr.GetStr(), &pEndPtr );
+ }
+
+ rPar.Get(0)->PutDouble( nResult );
+ }
+}
+
+RTLFUNC(DateSerial)
+{
+ if ( rPar.Count() < 4 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ INT16 nYear = rPar.Get(1)->GetInteger();
+ INT16 nMonth = rPar.Get(2)->GetInteger();
+ INT16 nDay = rPar.Get(3)->GetInteger();
+ if ( nYear < 100 )
+ nYear += 1900;
+ if ((nYear < 100 || nYear > 9999) ||
+ (nMonth < 1 || nMonth > 12 ) ||
+ (nDay < 1 || nDay > 31 ))
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ Date aCurDate( nDay, nMonth, nYear );
+ long nDiffDays = GetDayDiff( aCurDate );
+ rPar.Get(0)->PutDate( (double)nDiffDays ); // JSM
+}
+
+RTLFUNC(TimeSerial)
+{
+ if ( rPar.Count() < 4 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ INT16 nHour = rPar.Get(1)->GetInteger();
+ if ( nHour == 24 )
+ nHour = 0; // Wegen UNO DateTimes, die bis 24 Uhr gehen
+ INT16 nMinute = rPar.Get(2)->GetInteger();
+ INT16 nSecond = rPar.Get(3)->GetInteger();
+ if ((nHour < 0 || nHour > 23) ||
+ (nMinute < 0 || nMinute > 59 ) ||
+ (nSecond < 0 || nSecond > 59 ))
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ INT32 nSeconds = nHour;
+ nSeconds *= 3600;
+ nSeconds += nMinute * 60;
+ nSeconds += nSecond;
+ double nDays = ((double)nSeconds) / (double)(86400.0);
+ rPar.Get(0)->PutDate( nDays ); // JSM
+}
+
+RTLFUNC(DateValue)
+{
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ // #39629 pINST pruefen, kann aus URL-Zeile gerufen werden
+ SvNumberFormatter* pFormatter = NULL;
+ if( pINST )
+ pFormatter = pINST->GetNumberFormatter();
+ else
+ {
+ ULONG n; // Dummy
+ SbiInstance::PrepareNumberFormatter( pFormatter, n, n, n );
+ }
+
+ ULONG nIndex;
+ double fResult;
+ String aStr( rPar.Get(1)->GetString() );
+ BOOL bSuccess = pFormatter->IsNumberFormat( aStr, nIndex, fResult );
+ short nType = pFormatter->GetType( nIndex );
+ if(bSuccess && (nType==NUMBERFORMAT_DATE || nType==NUMBERFORMAT_DATETIME))
+ {
+ if ( nType == NUMBERFORMAT_DATETIME )
+ {
+ // Zeit abschneiden
+ if ( fResult > 0.0 )
+ fResult = floor( fResult );
+ else
+ fResult = ceil( fResult );
+ }
+ // fResult += 2.0; // Anpassung StarCalcFormatter
+ rPar.Get(0)->PutDate( fResult ); // JSM
+ }
+ else
+ StarBASIC::Error( SbERR_CONVERSION );
+
+ // #39629 pFormatter kann selbst angefordert sein
+ if( !pINST )
+ delete pFormatter;
+ }
+}
+
+RTLFUNC(TimeValue)
+{
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ // #39629 pINST pruefen, kann aus URL-Zeile gerufen werden
+ SvNumberFormatter* pFormatter = NULL;
+ if( pINST )
+ pFormatter = pINST->GetNumberFormatter();
+ else
+ {
+ ULONG n; // Dummy
+ SbiInstance::PrepareNumberFormatter( pFormatter, n, n, n );
+ }
+
+ ULONG nIndex;
+ double fResult;
+ BOOL bSuccess = pFormatter->IsNumberFormat( rPar.Get(1)->GetString(),
+ nIndex, fResult );
+ short nType = pFormatter->GetType(nIndex);
+ if(bSuccess && (nType==NUMBERFORMAT_TIME||nType==NUMBERFORMAT_DATETIME))
+ {
+ if ( nType == NUMBERFORMAT_DATETIME )
+ // Tage abschneiden
+ fResult = fmod( fResult, 1 );
+ rPar.Get(0)->PutDate( fResult ); // JSM
+ }
+ else
+ StarBASIC::Error( SbERR_CONVERSION );
+
+ // #39629 pFormatter kann selbst angefordert sein
+ if( !pINST )
+ delete pFormatter;
+ }
+}
+
+RTLFUNC(Day)
+{
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ SbxVariableRef pArg = rPar.Get( 1 );
+ double aDouble = pArg->GetDate();
+ aDouble -= 2.0; // normieren: 1.1.1900 => 0.0
+ Date aRefDate( 1, 1, 1900 );
+ // aDouble = Fix( aDouble );
+ if ( aDouble >= 0.0 )
+ {
+ aDouble = floor( aDouble );
+ aRefDate += (ULONG)aDouble;
+ }
+ else
+ {
+ aDouble = ceil( aDouble );
+ aRefDate -= (ULONG)(-1.0 * aDouble);
+ }
+ rPar.Get(0)->PutInteger( (INT16)(aRefDate.GetDay()));
+ }
+}
+
+RTLFUNC(Weekday)
+{
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ Date aRefDate( 1,1,1900 );
+ long nDays = (long) rPar.Get(1)->GetDate();
+ nDays -= 2; // normieren: 1.1.1900 => 0
+ aRefDate += nDays;
+ DayOfWeek aDay = aRefDate.GetDayOfWeek();
+ INT16 nDay;
+ if ( aDay != SUNDAY )
+ nDay = (INT16)aDay + 2;
+ else
+ nDay = 1; // 1==Sonntag
+ rPar.Get(0)->PutInteger( nDay );
+ }
+}
+
+RTLFUNC(Year)
+{
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ Date aRefDate( 1,1,1900 );
+ long nDays = (long) rPar.Get(1)->GetDate();
+ nDays -= 2; // normieren: 1.1.1900 => 0.0
+ aRefDate += nDays;
+ rPar.Get(0)->PutInteger( (INT16)(aRefDate.GetYear()) );
+ }
+}
+
+RTLFUNC(Hour)
+{
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ double nArg = rPar.Get(1)->GetDate();
+ if ( nArg < 0.0 )
+ nArg *= -1.0;
+ double nFrac = nArg - floor( nArg );
+ nFrac *= 86400.0;
+ INT32 nSeconds = (INT32)nFrac;
+ INT16 nHour = (INT16)(nSeconds / 3600);
+ rPar.Get(0)->PutInteger( nHour );
+ }
+}
+
+
+RTLFUNC(Minute)
+{
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ double nArg = rPar.Get(1)->GetDate();
+ if ( nArg < 0.0 )
+ nArg *= -1.0;
+ double nFrac = nArg - floor( nArg );
+ nFrac *= 86400.0;
+ INT32 nSeconds = (INT32)nFrac;
+ INT16 nTemp = (INT16)(nSeconds % 3600);
+ INT16 nMin = nTemp / 60;
+ rPar.Get(0)->PutInteger( nMin );
+ }
+}
+
+RTLFUNC(Month)
+{
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ Date aRefDate( 1,1,1900 );
+ long nDays = (long) rPar.Get(1)->GetDate();
+ nDays -= 2; // normieren: 1.1.1900 => 0.0
+ aRefDate += nDays;
+ rPar.Get(0)->PutInteger( (INT16)(aRefDate.GetMonth()) );
+ }
+}
+
+RTLFUNC(Second)
+{
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ double nArg = rPar.Get(1)->GetDate();
+ if ( nArg < 0.0 )
+ nArg *= -1.0;
+ double nFrac = nArg - floor( nArg );
+ nFrac *= 86400.0;
+ INT32 nSeconds = (INT32)nFrac;
+ INT16 nTemp = (INT16)(nSeconds / 3600);
+ nSeconds -= nTemp * 3600;
+ nTemp = (INT16)(nSeconds / 60);
+ nSeconds -= nTemp * 60;
+ rPar.Get(0)->PutInteger( (INT16)nSeconds );
+ }
+}
+
+// Date Now(void)
+
+RTLFUNC(Now)
+{
+ Date aDate;
+ Time aTime;
+ double aSerial = (double)GetDayDiff( aDate );
+ long nSeconds = aTime.GetHour();
+ nSeconds *= 3600;
+ nSeconds += aTime.GetMin() * 60;
+ nSeconds += aTime.GetSec();
+ double nDays = ((double)nSeconds) / (double)(24.0*3600.0);
+ aSerial += nDays;
+ rPar.Get(0)->PutDate( aSerial );
+}
+
+// Date Time(void)
+
+RTLFUNC(Time)
+{
+ if ( !bWrite )
+ {
+ Time aTime;
+ SbxVariable* pMeth = rPar.Get( 0 );
+ String aRes;
+ if( pMeth->IsFixed() )
+ {
+ // Time$: hh:mm:ss
+ char buf[ 20 ];
+ sprintf( buf, "%02d:%02d:%02d",
+ aTime.GetHour(), aTime.GetMin(), aTime.GetSec() );
+ aRes = String::CreateFromAscii( buf );
+ }
+ else
+ {
+ // Time: system dependent
+ long nSeconds=aTime.GetHour();
+ nSeconds *= 3600;
+ nSeconds += aTime.GetMin() * 60;
+ nSeconds += aTime.GetSec();
+ double nDays = (double)nSeconds * ( 1.0 / (24.0*3600.0) );
+ Color* pCol;
+
+ // #39629 pINST pruefen, kann aus URL-Zeile gerufen werden
+ SvNumberFormatter* pFormatter = NULL;
+ ULONG nIndex;
+ if( pINST )
+ {
+ pFormatter = pINST->GetNumberFormatter();
+ nIndex = pINST->GetStdTimeIdx();
+ }
+ else
+ {
+ ULONG n; // Dummy
+ SbiInstance::PrepareNumberFormatter( pFormatter, n, nIndex, n );
+ }
+
+ pFormatter->GetOutputString( nDays, nIndex, aRes, &pCol );
+
+ // #39629 pFormatter kann selbst angefordert sein
+ if( !pINST )
+ delete pFormatter;
+ }
+ pMeth->PutString( aRes );
+ }
+ else
+ {
+ StarBASIC::Error( SbERR_NOT_IMPLEMENTED );
+ }
+}
+
+RTLFUNC(Timer)
+{
+ Time aTime;
+ long nSeconds = aTime.GetHour();
+ nSeconds *= 3600;
+ nSeconds += aTime.GetMin() * 60;
+ nSeconds += aTime.GetSec();
+ rPar.Get(0)->PutDate( (double)nSeconds );
+}
+
+
+RTLFUNC(Date)
+{
+ if ( !bWrite )
+ {
+ Date aToday;
+ double nDays = (double)GetDayDiff( aToday );
+ SbxVariable* pMeth = rPar.Get( 0 );
+ if( pMeth->IsString() )
+ {
+ String aRes;
+ Color* pCol;
+
+ // #39629 pINST pruefen, kann aus URL-Zeile gerufen werden
+ SvNumberFormatter* pFormatter = NULL;
+ ULONG nIndex;
+ if( pINST )
+ {
+ pFormatter = pINST->GetNumberFormatter();
+ nIndex = pINST->GetStdDateIdx();
+ }
+ else
+ {
+ ULONG n; // Dummy
+ SbiInstance::PrepareNumberFormatter( pFormatter, nIndex, n, n );
+ }
+
+ pFormatter->GetOutputString( nDays, nIndex, aRes, &pCol );
+ pMeth->PutString( aRes );
+
+ // #39629 pFormatter kann selbst angefordert sein
+ if( !pINST )
+ delete pFormatter;
+ }
+ else
+ pMeth->PutDate( nDays );
+ }
+ else
+ {
+ StarBASIC::Error( SbERR_NOT_IMPLEMENTED );
+ }
+}
+
+RTLFUNC(IsArray)
+{
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ rPar.Get(0)->PutBool((rPar.Get(1)->GetType() & SbxARRAY) ? TRUE : FALSE );
+}
+
+RTLFUNC(IsObject)
+{
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ rPar.Get( 0 )->PutBool( rPar.Get(1)->IsObject() );
+}
+
+RTLFUNC(IsDate)
+{
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ // #46134 Nur String wird konvertiert, andere Typen ergeben FALSE
+ SbxVariableRef xArg = rPar.Get( 1 );
+ SbxDataType eType = xArg->GetType();
+ BOOL bDate = FALSE;
+
+ if( eType == SbxDATE )
+ {
+ bDate = TRUE;
+ }
+ else if( eType == SbxSTRING )
+ {
+ // Error loeschen
+ SbxError nPrevError = SbxBase::GetError();
+ SbxBase::ResetError();
+
+ // Konvertierung des Parameters nach SbxDATE erzwingen
+ xArg->SbxValue::GetDate();
+
+ // Bei Fehler ist es kein Date
+ bDate = !SbxBase::IsError();
+
+ // Error-Situation wiederherstellen
+ SbxBase::ResetError();
+ SbxBase::SetError( nPrevError );
+ }
+ rPar.Get( 0 )->PutBool( bDate );
+ }
+}
+
+RTLFUNC(IsEmpty)
+{
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ rPar.Get( 0 )->PutBool( rPar.Get(1)->IsEmpty() );
+}
+
+RTLFUNC(IsError)
+{
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ rPar.Get( 0 )->PutBool( rPar.Get(1)->IsErr() );
+}
+
+RTLFUNC(IsNull)
+{
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ // #51475 Wegen Uno-Objekten auch true liefern,
+ // wenn der pObj-Wert NULL ist
+ SbxVariableRef pArg = rPar.Get( 1 );
+ BOOL bNull = rPar.Get(1)->IsNull();
+ if( !bNull && pArg->GetType() == SbxOBJECT )
+ {
+ SbxBase* pObj = pArg->GetObject();
+ if( !pObj )
+ bNull = TRUE;
+ }
+ rPar.Get( 0 )->PutBool( bNull );
+ }
+}
+
+RTLFUNC(IsNumeric)
+{
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ rPar.Get( 0 )->PutBool( rPar.Get( 1 )->IsNumericRTL() );
+}
+
+// Das machen wir auf die billige Tour
+
+RTLFUNC(IsMissing)
+{
+ if ( rPar.Count() < 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ // #57915 Missing wird durch Error angezeigt
+ rPar.Get( 0 )->PutBool( rPar.Get(1)->IsErr() );
+}
+
+// Dir( [Maske] [,Attrs] )
+// ToDo: Library-globaler Datenbereich fuer Dir-Objekt und Flags
+
+static String getFileNameFromURL( const String& aURL );
+
+RTLFUNC(Dir)
+{
+ String aPath;
+
+ USHORT nParCount = rPar.Count();
+ if( nParCount > 3 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ SbiRTLData* pRTLData = pINST->GetRTLData();
+
+ // #34645: Kann auch von der URL-Zeile ueber 'macro: Dir' aufgerufen werden
+ // dann existiert kein pRTLData und die Methode muss verlassen werden
+ if( !pRTLData )
+ return;
+
+ // <-- UCB
+ if( hasUno() )
+ {
+ Reference< XSimpleFileAccess > xSFI = getFileAccess();
+ if( xSFI.is() )
+ {
+ if ( nParCount >= 2 )
+ {
+ String aStr = getFullPath( rPar.Get(1)->GetString() );
+ OUString aUNCPath;
+ FileBase::normalizePath( aStr, aUNCPath );
+ OUString aFileURLStr;
+ FileBase::getFileURLFromNormalizedPath( aUNCPath, aFileURLStr );
+
+ try
+ {
+ String aDirURLStr;
+ sal_Bool bFolder = sal_False;
+ try { bFolder = xSFI->isFolder( aFileURLStr ); }
+ catch( Exception & ) {}
+ //catch( ::ucb::ContentCreationException & e )
+ //{
+ //::ucb::ContentCreationException::Reason aReason = e.getReason();
+ //}
+
+ if( bFolder )
+ {
+ aDirURLStr = aFileURLStr;
+ }
+ else
+ {
+ INetURLObject aFileURL( aFileURLStr );
+
+ // Not folder but exists? Return file!
+ sal_Bool bExists = sal_False;
+ try { bExists = xSFI->exists( aFileURLStr ); }
+ //catch( ::ucb::ContentCreationException & e )
+ //{
+ //::ucb::ContentCreationException::Reason aReason = e.getReason();
+ //}
+ catch( Exception & ) {}
+ if( bExists )
+ {
+ String aNameOnlyStr = aFileURL.getName( INetURLObject::LAST_SEGMENT,
+ true, INetURLObject::DECODE_WITH_CHARSET );
+ rPar.Get(0)->PutString( aNameOnlyStr );
+ return;
+ }
+ aDirURLStr = aFileURL.GetPath();
+ }
+
+ USHORT nFlags = 0;
+ if ( nParCount > 2 )
+ pRTLData->nDirFlags = nFlags = rPar.Get(2)->GetInteger();
+ else
+ pRTLData->nDirFlags = 0;
+
+ // Read directory
+ sal_Bool bIncludeFolders = ((nFlags & Sb_ATTR_DIRECTORY) != 0);
+ pRTLData->aDirSeq = xSFI->getFolderContents( aDirURLStr, bIncludeFolders );
+ pRTLData->nCurDirPos = 0;
+ }
+ catch( Exception & )
+ {
+ //StarBASIC::Error( ERRCODE_IO_GENERAL );
+ }
+ }
+
+
+ if( pRTLData->aDirSeq.getLength() > 0 )
+ {
+ sal_Bool bOnlyFolders = ((pRTLData->nDirFlags & Sb_ATTR_DIRECTORY) != 0);
+ for( ;; )
+ {
+ if( pRTLData->nCurDirPos >= pRTLData->aDirSeq.getLength() )
+ {
+ pRTLData->aDirSeq.realloc( 0 );
+ aPath.Erase();
+ break;
+ }
+ else
+ {
+ OUString aFile = pRTLData->aDirSeq.getConstArray()[pRTLData->nCurDirPos++];
+
+ // Only directories?
+ if( bOnlyFolders )
+ {
+ sal_Bool bFolder = sal_False;
+ try { bFolder = xSFI->isFolder( aFile ); }
+ catch( Exception & ) {}
+ if( !bFolder )
+ continue;
+ }
+
+ INetURLObject aURL( aFile );
+ aPath = aURL.getName( INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::DECODE_WITH_CHARSET );
+ break;
+ }
+ }
+ }
+ rPar.Get(0)->PutString( aPath );
+ }
+ }
+ else
+ // --> UCB
+ {
+ if ( nParCount >= 2 )
+ {
+ delete pRTLData->pDir;
+ pRTLData->pDir = 0; // wg. Sonderbehandlung Sb_ATTR_VOLUME
+ DirEntry aEntry( rPar.Get(1)->GetString() );
+ FileStat aStat( aEntry );
+ if(!aStat.GetError() && (aStat.GetKind() & FSYS_KIND_FILE))
+ {
+ // ah ja, ist nur ein dateiname
+ // Pfad abschneiden (wg. VB4)
+ rPar.Get(0)->PutString( aEntry.GetName() );
+ return;
+ }
+ USHORT nFlags = 0;
+ if ( nParCount > 2 )
+ pRTLData->nDirFlags = nFlags = rPar.Get(2)->GetInteger();
+ else
+ pRTLData->nDirFlags = 0;
+ // Nur diese Bitmaske ist unter Windows erlaubt
+ #ifdef WIN
+ if( nFlags & ~0x1E )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT ), pRTLData->nDirFlags = 0;
+ #endif
+ // Sb_ATTR_VOLUME wird getrennt gehandelt
+ if( pRTLData->nDirFlags & Sb_ATTR_VOLUME )
+ aPath = aEntry.GetVolume();
+ else
+ {
+ // Die richtige Auswahl treffen
+ USHORT nMode = FSYS_KIND_FILE;
+ if( nFlags & Sb_ATTR_DIRECTORY )
+ nMode |= FSYS_KIND_DIR;
+ if( nFlags == Sb_ATTR_DIRECTORY )
+ nMode = FSYS_KIND_DIR;
+ pRTLData->pDir = new Dir( aEntry, (DirEntryKind) nMode );
+ pRTLData->nCurDirPos = 0;
+ }
+ }
+
+ if( pRTLData->pDir )
+ {
+ for( ;; )
+ {
+ if( pRTLData->nCurDirPos >= pRTLData->pDir->Count() )
+ {
+ delete pRTLData->pDir;
+ pRTLData->pDir = 0;
+ aPath.Erase();
+ break;
+ }
+ DirEntry aNextEntry=(*(pRTLData->pDir))[pRTLData->nCurDirPos++];
+ aPath = aNextEntry.GetName(); //Full();
+ #ifdef WIN
+ aNextEntry.ToAbs();
+ String sFull(aNextEntry.GetFull());
+ unsigned nFlags;
+
+ if (_dos_getfileattr( sFull.GetStr(), &nFlags ))
+ StarBASIC::Error( SbERR_FILE_NOT_FOUND );
+ else
+ {
+ INT16 nCurFlags = pRTLData->nDirFlags;
+ if( (nCurFlags == Sb_ATTR_NORMAL)
+ && !(nFlags & ( _A_HIDDEN | _A_SYSTEM | _A_VOLID | _A_SUBDIR ) ) )
+ break;
+ else if( (nCurFlags & Sb_ATTR_HIDDEN) && (nFlags & _A_HIDDEN) )
+ break;
+ else if( (nCurFlags & Sb_ATTR_SYSTEM) && (nFlags & _A_SYSTEM) )
+ break;
+ else if( (nCurFlags & Sb_ATTR_VOLUME) && (nFlags & _A_VOLID) )
+ break;
+ else if( (nCurFlags & Sb_ATTR_DIRECTORY) && (nFlags & _A_SUBDIR) )
+ break;
+ }
+ #else
+ break;
+ #endif
+ }
+ }
+ rPar.Get(0)->PutString( aPath );
+ }
+ }
+}
+
+
+RTLFUNC(GetAttr)
+{
+ if ( rPar.Count() == 2 )
+ {
+ INT16 nFlags = 0;
+
+ // <-- UCB
+ if( hasUno() )
+ {
+ Reference< XSimpleFileAccess > xSFI = getFileAccess();
+ if( xSFI.is() )
+ {
+ try
+ {
+ String aPath = getFullPath( rPar.Get(1)->GetString() );
+ sal_Bool bExists = sal_False;
+ try { bExists = xSFI->exists( aPath ); }
+ catch( Exception & ) {}
+ if( !bExists )
+ {
+ StarBASIC::Error( SbERR_FILE_NOT_FOUND );
+ return;
+ }
+
+ sal_Bool bReadOnly = xSFI->isReadOnly( aPath );
+ sal_Bool bDirectory = xSFI->isFolder( aPath );
+ if( bReadOnly )
+ nFlags |= 0x0001; // ATTR_READONLY
+ if( bDirectory )
+ nFlags |= 0x0010; // ATTR_DIRECTORY
+ }
+ catch( Exception & )
+ {
+ StarBASIC::Error( ERRCODE_IO_GENERAL );
+ }
+ }
+ }
+ else
+ // --> UCB
+ {
+ DirEntry aEntry( rPar.Get(1)->GetString() );
+ aEntry.ToAbs();
+ BOOL bUseFileStat = FALSE;
+
+ // #57064 Bei virtuellen URLs den Real-Path extrahieren
+ String aFile = aEntry.GetFull();
+ ByteString aByteStrFullPath( aEntry.GetFull(), gsl_getSystemTextEncoding() );
+ #if defined( WIN )
+ int nErr = _dos_getfileattr( aByteStrFullPath.GetBuffer(),(unsigned *) &nFlags );
+ if ( nErr )
+ StarBASIC::Error( SbERR_FILE_NOT_FOUND );
+ #elif defined( WNT )
+ DWORD nRealFlags = GetFileAttributes (aByteStrFullPath.GetBuffer());
+ if (nRealFlags != 0xffffffff)
+ {
+ if (nRealFlags == FILE_ATTRIBUTE_NORMAL)
+ nRealFlags = 0;
+ nFlags = (INT16) (nRealFlags);
+ }
+ else
+ StarBASIC::Error( SbERR_FILE_NOT_FOUND );
+ #elif defined( OS2 )
+ FILESTATUS3 aFileStatus;
+ APIRET rc = DosQueryPathInfo(aByteStrFullPath.GetBuffer(),1,
+ &aFileStatus,sizeof(FILESTATUS3));
+ if (!rc)
+ nFlags = (INT16) aFileStatus.attrFile;
+ else
+ StarBASIC::Error( SbERR_FILE_NOT_FOUND );
+ #else
+ bUseFileStat = TRUE;
+ #endif
+ if( bUseFileStat )
+ {
+ if( FileStat::GetReadOnlyFlag( aEntry ) )
+ nFlags |= 0x0001; // ATTR_READONLY
+ FileStat aStat( aEntry );
+ DirEntryKind eKind = aStat.GetKind();
+ if( eKind & FSYS_KIND_DIR )
+ nFlags |= 0x0010; // ATTR_DIRECTORY
+ if( aEntry.GetFlag() & FSYS_FLAG_VOLUME )
+ nFlags |= 0x0008; // ATTR_VOLUME
+ }
+ }
+ rPar.Get(0)->PutInteger( nFlags );
+ }
+ else
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+}
+
+
+RTLFUNC(FileDateTime)
+{
+ if ( rPar.Count() != 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+
+ // <-- UCB
+ String aPath = rPar.Get(1)->GetString();
+ Time aTime;
+ Date aDate;
+ if( hasUno() )
+ {
+ Reference< XSimpleFileAccess > xSFI = getFileAccess();
+ if( xSFI.is() )
+ {
+ try
+ {
+ com::sun::star::util::DateTime aUnoDT = xSFI->getDateTimeModified( aPath );
+ aTime = Time( aUnoDT.Hours, aUnoDT.Minutes, aUnoDT.Seconds, aUnoDT.HundredthSeconds );
+ aDate = Date( aUnoDT.Day, aUnoDT.Month, aUnoDT.Year );
+ }
+ catch( Exception & )
+ {
+ StarBASIC::Error( ERRCODE_IO_GENERAL );
+ }
+ }
+ }
+ else
+ // --> UCB
+ {
+ DirEntry aEntry( aPath );
+ FileStat aStat( aEntry );
+ aTime = Time( aStat.TimeModified() );
+ aDate = Date( aStat.DateModified() );
+ }
+
+ double fSerial = (double)GetDayDiff( aDate );
+ long nSeconds = aTime.GetHour();
+ nSeconds *= 3600;
+ nSeconds += aTime.GetMin() * 60;
+ nSeconds += aTime.GetSec();
+ double nDays = ((double)nSeconds) / (double)(24.0*3600.0);
+ fSerial += nDays;
+
+ Color* pCol;
+
+ // #39629 pINST pruefen, kann aus URL-Zeile gerufen werden
+ SvNumberFormatter* pFormatter = NULL;
+ ULONG nIndex;
+ if( pINST )
+ {
+ pFormatter = pINST->GetNumberFormatter();
+ nIndex = pINST->GetStdDateTimeIdx();
+ }
+ else
+ {
+ ULONG n; // Dummy
+ SbiInstance::PrepareNumberFormatter( pFormatter, n, n, nIndex );
+ }
+
+ String aRes;
+ pFormatter->GetOutputString( fSerial, nIndex, aRes, &pCol );
+ rPar.Get(0)->PutString( aRes );
+
+ // #39629 pFormatter kann selbst angefordert sein
+ if( !pINST )
+ delete pFormatter;
+ }
+}
+
+
+RTLFUNC(EOF)
+{
+ // AB 08/16/2000: No changes for UCB
+ if ( rPar.Count() != 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ INT16 nChannel = rPar.Get(1)->GetInteger();
+ // nChannel--; // macht MD beim Oeffnen auch nicht
+ SbiIoSystem* pIO = pINST->GetIoSystem();
+ SbiStream* pSbStrm = pIO->GetStream( nChannel );
+ if ( !pSbStrm )
+ {
+ StarBASIC::Error( SbERR_BAD_CHANNEL );
+ return;
+ }
+ BOOL bIsEof;
+ SvStream* pSvStrm = pSbStrm->GetStrm();
+ if ( pSbStrm->IsText() )
+ {
+ char cBla;
+ (*pSvStrm) >> cBla; // koennen wir noch ein Zeichen lesen
+ bIsEof = pSvStrm->IsEof();
+ if ( !bIsEof )
+ pSvStrm->SeekRel( -1 );
+ }
+ else
+ bIsEof = pSvStrm->IsEof(); // fuer binaerdateien!
+ rPar.Get(0)->PutBool( bIsEof );
+ }
+}
+
+RTLFUNC(FileAttr)
+{
+ // AB 08/16/2000: No changes for UCB
+
+ // #57064 Obwohl diese Funktion nicht mit DirEntry arbeitet, ist sie von
+ // der Anpassung an virtuelle URLs nich betroffen, da sie nur auf bereits
+ // geoeffneten Dateien arbeitet und der Name hier keine Rolle spielt.
+
+ if ( rPar.Count() != 3 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ INT16 nChannel = rPar.Get(1)->GetInteger();
+// nChannel--;
+ SbiIoSystem* pIO = pINST->GetIoSystem();
+ SbiStream* pSbStrm = pIO->GetStream( nChannel );
+ if ( !pSbStrm )
+ {
+ StarBASIC::Error( SbERR_BAD_CHANNEL );
+ return;
+ }
+ INT16 nRet;
+ if ( rPar.Get(2)->GetInteger() == 1 )
+ nRet = (INT16)(pSbStrm->GetMode());
+ else
+ nRet = 0; // System file handle not supported
+
+ rPar.Get(0)->PutInteger( nRet );
+ }
+}
+RTLFUNC(Loc)
+{
+ // AB 08/16/2000: No changes for UCB
+ if ( rPar.Count() != 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ INT16 nChannel = rPar.Get(1)->GetInteger();
+ SbiIoSystem* pIO = pINST->GetIoSystem();
+ SbiStream* pSbStrm = pIO->GetStream( nChannel );
+ if ( !pSbStrm )
+ {
+ StarBASIC::Error( SbERR_BAD_CHANNEL );
+ return;
+ }
+ SvStream* pSvStrm = pSbStrm->GetStrm();
+ ULONG nPos;
+ if( pSbStrm->IsRandom())
+ {
+ short nBlockLen = pSbStrm->GetBlockLen();
+ nPos = nBlockLen ? (pSvStrm->Tell() / nBlockLen) : 0;
+ nPos++; // Blockpositionen beginnen bei 1
+ }
+ else if ( pSbStrm->IsText() )
+ nPos = pSbStrm->GetLine();
+ else if( pSbStrm->IsBinary() )
+ nPos = pSvStrm->Tell();
+ else if ( pSbStrm->IsSeq() )
+ nPos = ( pSvStrm->Tell()+1 ) / 128;
+ else
+ nPos = pSvStrm->Tell();
+ rPar.Get(0)->PutLong( (INT32)nPos );
+ }
+}
+
+RTLFUNC(Lof)
+{
+ // AB 08/16/2000: No changes for UCB
+ if ( rPar.Count() != 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ INT16 nChannel = rPar.Get(1)->GetInteger();
+ SbiIoSystem* pIO = pINST->GetIoSystem();
+ SbiStream* pSbStrm = pIO->GetStream( nChannel );
+ if ( !pSbStrm )
+ {
+ StarBASIC::Error( SbERR_BAD_CHANNEL );
+ return;
+ }
+ SvStream* pSvStrm = pSbStrm->GetStrm();
+ ULONG nOldPos = pSvStrm->Tell();
+ ULONG nLen = pSvStrm->Seek( STREAM_SEEK_TO_END );
+ pSvStrm->Seek( nOldPos );
+ rPar.Get(0)->PutLong( (INT32)nLen );
+ }
+}
+
+
+RTLFUNC(Seek)
+{
+ // AB 08/16/2000: No changes for UCB
+ int nArgs = (int)rPar.Count();
+ if ( nArgs < 2 || nArgs > 3 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ INT16 nChannel = rPar.Get(1)->GetInteger();
+// nChannel--;
+ SbiIoSystem* pIO = pINST->GetIoSystem();
+ SbiStream* pSbStrm = pIO->GetStream( nChannel );
+ if ( !pSbStrm )
+ {
+ StarBASIC::Error( SbERR_BAD_CHANNEL );
+ return;
+ }
+ SvStream* pStrm = pSbStrm->GetStrm();
+
+ if ( nArgs == 2 ) // Seek-Function
+ {
+ ULONG nPos = pStrm->Tell();
+ if( pSbStrm->IsRandom() )
+ nPos = nPos / pSbStrm->GetBlockLen();
+ nPos++; // Basic zaehlt ab 1
+ rPar.Get(0)->PutLong( (INT32)nPos );
+ }
+ else // Seek-Statement
+ {
+ INT32 nPos = rPar.Get(2)->GetLong();
+ if ( nPos < 1 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ nPos--; // Basic zaehlt ab 1, SvStreams zaehlen ab 0
+ pSbStrm->SetExpandOnWriteTo( 0 );
+ if ( pSbStrm->IsRandom() )
+ nPos *= pSbStrm->GetBlockLen();
+ pStrm->Seek( (ULONG)nPos );
+ pSbStrm->SetExpandOnWriteTo( nPos );
+ }
+}
+
+RTLFUNC(Format)
+{
+ USHORT nArgCount = (USHORT)rPar.Count();
+ if ( nArgCount < 2 || nArgCount > 3 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ String aResult;
+ if( nArgCount == 2 )
+ rPar.Get(1)->Format( aResult );
+ else
+ {
+ String aFmt( rPar.Get(2)->GetString() );
+ rPar.Get(1)->Format( aResult, &aFmt );
+ }
+ rPar.Get(0)->PutString( aResult );
+ }
+}
+
+RTLFUNC(Randomize)
+{
+ if ( rPar.Count() > 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ INT16 nSeed;
+ if( rPar.Count() == 2 )
+ nSeed = (INT16)rPar.Get(1)->GetInteger();
+ else
+ nSeed = (INT16)rand();
+ srand( nSeed );
+}
+
+RTLFUNC(Rnd)
+{
+ if ( rPar.Count() > 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ double nRand = (double)rand();
+ nRand = ( nRand / (double)RAND_MAX );
+ rPar.Get(0)->PutDouble( nRand );
+ }
+}
+
+
+//
+// Syntax: Shell("Path",[ Window-Style,[ "Params", [ bSync = FALSE ]]])
+//
+// WindowStyles (VBA-kompatibel):
+// 2 == Minimized
+// 3 == Maximized
+// 10 == Full-Screen (Textmodus-Anwendungen OS/2, WIN95, WNT)
+//
+// !!!HACK der WindowStyle wird im Creator an Application::StartApp
+// uebergeben. Format: "xxxx2"
+//
+
+
+RTLFUNC(Shell)
+{
+ // No shell command for "virtual" portal users
+ if( needSecurityRestrictions() )
+ {
+ StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
+ return;
+ }
+
+ if ( rPar.Count() < 2 || rPar.Count() > 5 )
+ {
+ rPar.Get(0)->PutLong(0);
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ }
+ else
+ {
+ USHORT nOptions = NAMESPACE_VOS(OProcess)::TOption_SearchPath|
+ NAMESPACE_VOS(OProcess)::TOption_Detached;
+ String aCmdLine = rPar.Get(1)->GetString();
+ // Zusaetzliche Parameter anhaengen, es muss eh alles geparsed werden
+ if( rPar.Count() >= 4 )
+ {
+ aCmdLine.AppendAscii( " " );
+ aCmdLine += rPar.Get(3)->GetString();
+ }
+ else if( !aCmdLine.Len() )
+ {
+ // Spezial-Behandlung (leere Liste) vermeiden
+ aCmdLine.AppendAscii( " " );
+ }
+ USHORT nLen = aCmdLine.Len();
+
+ // #55735 Wenn Parameter dabei sind, muessen die abgetrennt werden
+ // #72471 Auch die einzelnen Parameter trennen
+ std::list<String> aTokenList;
+ String aToken;
+ USHORT i = 0;
+ char c;
+ while( i < nLen )
+ {
+ // Spaces weg
+ while( ( c = aCmdLine.GetBuffer()[ i ] ) == ' ' || c == '\t' )
+ i++;
+
+ if( c == '\"' || c == '\'' )
+ {
+ USHORT iFoundPos = aCmdLine.Search( c, i + 1 );
+
+ // Wenn nichts gefunden wurde, Rest kopieren
+ if( iFoundPos == STRING_NOTFOUND )
+ {
+ aToken = aCmdLine.Copy( i, STRING_LEN );
+ i = nLen;
+ }
+ else
+ {
+ aToken = aCmdLine.Copy( i + 1, (iFoundPos - i - 1) );
+ i = iFoundPos + 1;
+ }
+ }
+ else
+ {
+ USHORT iFoundSpacePos = aCmdLine.Search( ' ', i );
+ USHORT iFoundTabPos = aCmdLine.Search( '\t', i );
+ USHORT iFoundPos = Min( iFoundSpacePos, iFoundTabPos );
+
+ // Wenn nichts gefunden wurde, Rest kopieren
+ if( iFoundPos == STRING_NOTFOUND )
+ {
+ aToken = aCmdLine.Copy( i, STRING_LEN );
+ i = nLen;
+ }
+ else
+ {
+ aToken = aCmdLine.Copy( i, (iFoundPos - i) );
+ i = iFoundPos;
+ }
+ }
+
+ // In die Liste uebernehmen
+ aTokenList.push_back( aToken );
+ }
+ // #55735 / #72471 Ende
+
+ INT16 nWinStyle = 0;
+ if( rPar.Count() >= 3 )
+ {
+ nWinStyle = rPar.Get(2)->GetInteger();
+ switch( nWinStyle )
+ {
+ case 2:
+ nOptions |= NAMESPACE_VOS(OProcess)::TOption_Minimized;
+ break;
+ case 3:
+ nOptions |= NAMESPACE_VOS(OProcess)::TOption_Maximized;
+ break;
+ case 10:
+ nOptions |= NAMESPACE_VOS(OProcess)::TOption_FullScreen;
+ break;
+ }
+ }
+ NAMESPACE_VOS(OProcess)::TProcessOption eOptions =
+ (NAMESPACE_VOS(OProcess)::TProcessOption)nOptions;
+
+
+ // #72471 Parameter aufbereiten
+ std::list<String>::const_iterator iter = aTokenList.begin();
+ const String& rStr = *iter;
+ NAMESPACE_RTL(OUString) aOUStrProg( rStr.GetBuffer(), rStr.Len() );
+ iter++;
+
+ USHORT nParamCount = aTokenList.size() - 1;
+ NAMESPACE_RTL(OUString)* pArgumentList = NULL;
+ //const char** pParamList = NULL;
+ if( nParamCount )
+ {
+ pArgumentList = new NAMESPACE_RTL(OUString)[ nParamCount ];
+ //pParamList = new const char*[ nParamCount ];
+ USHORT iList = 0;
+ while( iter != aTokenList.end() )
+ {
+ const String& rParamStr = (*iter);
+ pArgumentList[iList++] = NAMESPACE_RTL(OUString)( rParamStr.GetBuffer(), rParamStr.Len() );
+ //pParamList[iList++] = (*iter).GetStr();
+ iter++;
+ }
+ }
+
+ //const char* pParams = aParams.Len() ? aParams.GetStr() : 0;
+ NAMESPACE_VOS(OProcess)* pApp;
+ pApp = new NAMESPACE_VOS(OProcess)( aOUStrProg );
+ BOOL bSucc;
+ if( nParamCount == 0 )
+ {
+ bSucc = pApp->execute( eOptions ) == NAMESPACE_VOS(OProcess)::E_None;
+ }
+ else
+ {
+ NAMESPACE_VOS(OArgumentList) aArgList( pArgumentList, nParamCount );
+ bSucc = pApp->execute( eOptions, aArgList ) == NAMESPACE_VOS(OProcess)::E_None;
+ }
+
+ /*
+ if( nParamCount == 0 )
+ pApp = new NAMESPACE_VOS(OProcess)( pProg );
+ else
+ pApp = new NAMESPACE_VOS(OProcess)( pProg, pParamList, nParamCount );
+ BOOL bSucc = pApp->execute( eOptions ) == NAMESPACE_VOS(OProcess)::E_None;
+ */
+
+ delete pApp;
+ delete[] pArgumentList;
+ if( !bSucc )
+ StarBASIC::Error( SbERR_FILE_NOT_FOUND );
+ else
+ rPar.Get(0)->PutLong( 0 );
+ }
+}
+
+RTLFUNC(VarType)
+{
+ if ( rPar.Count() != 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ SbxDataType eType = rPar.Get(1)->GetType();
+ rPar.Get(0)->PutInteger( (INT16)eType );
+ }
+}
+
+RTLFUNC(TypeName)
+{
+ static const char* pTypeNames[] =
+ {
+ "Empty",
+ "Null",
+ "Integer",
+ "Long",
+ "Single",
+ "Double",
+ "Currency",
+ "Date",
+ "String",
+ "Object",
+ "Error",
+ "Boolean",
+ "Variant",
+ "DataObject",
+ "Unknown Type",
+ "Unknown Type",
+ "Char",
+ "Byte",
+ "UShort",
+ "ULong",
+ "Long64",
+ "ULong64",
+ "Int",
+ "UInt",
+ "Void",
+ "HResult",
+ "Pointer",
+ "DimArray",
+ "CArray",
+ "Userdef",
+ "Lpstr",
+ "Lpwstr",
+ "Unknown Type",
+ };
+
+ if ( rPar.Count() != 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ SbxDataType eType = rPar.Get(1)->GetType();
+ BOOL bIsArray = ( ( eType & SbxARRAY ) != 0 );
+ int nPos = ((int)eType) & 0x0FFF;
+ USHORT nTypeNameCount = sizeof( pTypeNames ) / sizeof( char* );
+ if ( nPos < 0 || nPos >= nTypeNameCount )
+ nPos = nTypeNameCount - 1;
+ String aRetStr = String::CreateFromAscii( pTypeNames[nPos] );
+ if( bIsArray )
+ aRetStr.AppendAscii( "()" );
+ rPar.Get(0)->PutString( aRetStr );
+ }
+}
+
+RTLFUNC(Len)
+{
+ if ( rPar.Count() != 2 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else
+ {
+ const String& rStr = rPar.Get(1)->GetString();
+ rPar.Get(0)->PutLong( (INT32)rStr.Len() );
+ }
+}
+
+RTLFUNC(DDEInitiate)
+{
+ // No DDE for "virtual" portal users
+ if( needSecurityRestrictions() )
+ {
+ StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
+ return;
+ }
+
+ int nArgs = (int)rPar.Count();
+ if ( nArgs != 3 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ const String& rApp = rPar.Get(1)->GetString();
+ const String& rTopic = rPar.Get(2)->GetString();
+
+ SbiDdeControl* pDDE = pINST->GetDdeControl();
+ INT16 nChannel;
+ SbError nDdeErr = pDDE->Initiate( rApp, rTopic, nChannel );
+ if( nDdeErr )
+ StarBASIC::Error( nDdeErr );
+ else
+ rPar.Get(0)->PutInteger( nChannel );
+}
+
+RTLFUNC(DDETerminate)
+{
+ // No DDE for "virtual" portal users
+ if( needSecurityRestrictions() )
+ {
+ StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
+ return;
+ }
+
+ rPar.Get(0)->PutEmpty();
+ int nArgs = (int)rPar.Count();
+ if ( nArgs != 2 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ INT16 nChannel = rPar.Get(1)->GetInteger();
+ SbiDdeControl* pDDE = pINST->GetDdeControl();
+ SbError nDdeErr = pDDE->Terminate( nChannel );
+ if( nDdeErr )
+ StarBASIC::Error( nDdeErr );
+}
+
+RTLFUNC(DDETerminateAll)
+{
+ // No DDE for "virtual" portal users
+ if( needSecurityRestrictions() )
+ {
+ StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
+ return;
+ }
+
+ rPar.Get(0)->PutEmpty();
+ int nArgs = (int)rPar.Count();
+ if ( nArgs != 1 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ SbiDdeControl* pDDE = pINST->GetDdeControl();
+ SbError nDdeErr = pDDE->TerminateAll();
+ if( nDdeErr )
+ StarBASIC::Error( nDdeErr );
+
+}
+
+RTLFUNC(DDERequest)
+{
+ // No DDE for "virtual" portal users
+ if( needSecurityRestrictions() )
+ {
+ StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
+ return;
+ }
+
+ int nArgs = (int)rPar.Count();
+ if ( nArgs != 3 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ INT16 nChannel = rPar.Get(1)->GetInteger();
+ const String& rItem = rPar.Get(2)->GetString();
+ SbiDdeControl* pDDE = pINST->GetDdeControl();
+ String aResult;
+ SbError nDdeErr = pDDE->Request( nChannel, rItem, aResult );
+ if( nDdeErr )
+ StarBASIC::Error( nDdeErr );
+ else
+ rPar.Get(0)->PutString( aResult );
+}
+
+RTLFUNC(DDEExecute)
+{
+ // No DDE for "virtual" portal users
+ if( needSecurityRestrictions() )
+ {
+ StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
+ return;
+ }
+
+ rPar.Get(0)->PutEmpty();
+ int nArgs = (int)rPar.Count();
+ if ( nArgs != 3 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ INT16 nChannel = rPar.Get(1)->GetInteger();
+ const String& rCommand = rPar.Get(2)->GetString();
+ SbiDdeControl* pDDE = pINST->GetDdeControl();
+ SbError nDdeErr = pDDE->Execute( nChannel, rCommand );
+ if( nDdeErr )
+ StarBASIC::Error( nDdeErr );
+}
+
+RTLFUNC(DDEPoke)
+{
+ // No DDE for "virtual" portal users
+ if( needSecurityRestrictions() )
+ {
+ StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
+ return;
+ }
+
+ rPar.Get(0)->PutEmpty();
+ int nArgs = (int)rPar.Count();
+ if ( nArgs != 4 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ INT16 nChannel = rPar.Get(1)->GetInteger();
+ const String& rItem = rPar.Get(2)->GetString();
+ const String& rData = rPar.Get(3)->GetString();
+ SbiDdeControl* pDDE = pINST->GetDdeControl();
+ SbError nDdeErr = pDDE->Poke( nChannel, rItem, rData );
+ if( nDdeErr )
+ StarBASIC::Error( nDdeErr );
+}
+
+
+RTLFUNC(FreeFile)
+{
+ if ( rPar.Count() != 1 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ SbiIoSystem* pIO = pINST->GetIoSystem();
+ short nChannel = 1;
+ while( nChannel < CHANNELS )
+ {
+ SbiStream* pStrm = pIO->GetStream( nChannel );
+ if( !pStrm )
+ {
+ rPar.Get(0)->PutInteger( nChannel );
+ return;
+ }
+ nChannel++;
+ }
+ StarBASIC::Error( SbERR_TOO_MANY_FILES );
+}
+
+RTLFUNC(LBound)
+{
+ USHORT nParCount = rPar.Count();
+ if ( nParCount != 3 && nParCount != 2 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ SbxBase* pParObj = rPar.Get(1)->GetObject();
+ SbxDimArray* pArr = PTR_CAST(SbxDimArray,pParObj);
+ if( pArr )
+ {
+ short nLower, nUpper;
+ short nDim = (nParCount == 3) ? (short)rPar.Get(2)->GetInteger() : 1;
+ if( !pArr->GetDim( nDim, nLower, nUpper ) )
+ StarBASIC::Error( SbERR_OUT_OF_RANGE );
+ else
+ rPar.Get(0)->PutInteger( (INT16)nLower );
+ }
+ else
+ StarBASIC::Error( SbERR_MUST_HAVE_DIMS );
+}
+
+RTLFUNC(UBound)
+{
+ USHORT nParCount = rPar.Count();
+ if ( nParCount != 3 && nParCount != 2 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ SbxBase* pParObj = rPar.Get(1)->GetObject();
+ SbxDimArray* pArr = PTR_CAST(SbxDimArray,pParObj);
+ if( pArr )
+ {
+ short nLower, nUpper;
+ short nDim = (nParCount == 3) ? (short)rPar.Get(2)->GetInteger() : 1;
+ if( !pArr->GetDim( nDim, nLower, nUpper ) )
+ StarBASIC::Error( SbERR_OUT_OF_RANGE );
+ else
+ rPar.Get(0)->PutInteger( (INT16)nUpper );
+ }
+ else
+ StarBASIC::Error( SbERR_MUST_HAVE_DIMS );
+}
+
+RTLFUNC(RGB)
+{
+ if ( rPar.Count() != 4 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ ULONG nRed = rPar.Get(1)->GetInteger() & 0xFF;
+ ULONG nGreen = rPar.Get(2)->GetInteger() & 0xFF;
+ ULONG nBlue = rPar.Get(3)->GetInteger() & 0xFF;
+ ULONG nRGB = (nRed << 16) | (nGreen << 8) | nBlue;
+ rPar.Get(0)->PutLong( nRGB );
+}
+
+RTLFUNC(QBColor)
+{
+ if ( rPar.Count() != 2 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ Color aCol( (ColorName)rPar.Get(1)->GetInteger() );
+
+ ULONG nRed = aCol.GetRed() >> 8;
+ ULONG nGreen = aCol.GetGreen() >> 8;
+ ULONG nBlue = aCol.GetBlue() >> 8;
+ ULONG nRGB = (nRed << 16) | (nGreen << 8) | nBlue;
+ rPar.Get(0)->PutLong( nRGB );
+}
+
+
+RTLFUNC(StrConv)
+{
+ DBG_ASSERT(0,"StrConv:Not implemented");
+// if ( rPar.Count() != 3 )
+// {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+// return;
+// }
+}
+
+RTLFUNC(Beep)
+{
+ if ( rPar.Count() != 1 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ Sound::Beep();
+}
+
+RTLFUNC(Load)
+{
+ if( rPar.Count() != 2 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ // Diesen Call einfach an das Object weiterreichen
+ SbxBase* pObj = (SbxObject*)rPar.Get(1)->GetObject();
+ if( pObj && pObj->IsA( TYPE( SbxObject ) ) )
+ {
+ SbxVariable* pVar = ((SbxObject*)pObj)->
+ Find( String( RTL_CONSTASCII_USTRINGPARAM("Load") ), SbxCLASS_METHOD );
+ if( pVar )
+ pVar->GetInteger();
+ }
+}
+
+RTLFUNC(Unload)
+{
+ rPar.Get(0)->PutEmpty();
+ if( rPar.Count() != 2 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ // Diesen Call einfach an das Object weitereichen
+ SbxBase* pObj = (SbxObject*)rPar.Get(1)->GetObject();
+ if( pObj && pObj->IsA( TYPE( SbxObject ) ) )
+ {
+ SbxVariable* pVar = ((SbxObject*)pObj)->
+ Find( String( RTL_CONSTASCII_USTRINGPARAM("Unload") ), SbxCLASS_METHOD );
+ if( pVar )
+ pVar->GetInteger();
+ }
+}
+
+RTLFUNC(LoadPicture)
+{
+ if( rPar.Count() != 2 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ SbxObjectRef xRef = new SbStdPicture;
+
+ SvFileStream aIStream( rPar.Get(1)->GetString(), STREAM_READ );
+ Bitmap aBmp;
+ aIStream >> aBmp;
+ Graphic aGraphic( aBmp );
+ ((SbStdPicture*)(SbxObject*)xRef)->SetGraphic( aGraphic );
+ rPar.Get(0)->PutObject( xRef );
+}
+
+RTLFUNC(SavePicture)
+{
+ rPar.Get(0)->PutEmpty();
+ if( rPar.Count() != 3 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+
+ SbxBase* pObj = (SbxObject*)rPar.Get(1)->GetObject();
+ if( pObj->IsA( TYPE( SbStdPicture ) ) )
+ {
+ SvFileStream aOStream( rPar.Get(2)->GetString(), STREAM_WRITE | STREAM_TRUNC );
+ Graphic aGraphic = ((SbStdPicture*)pObj)->GetGraphic();
+ aOStream << aGraphic;
+ }
+}
+
+
+//-----------------------------------------------------------------------------------------
+/*
+class SbiAboutStarBasicDlg : public ModalDialog
+{
+ OKButton aOkButton;
+ Control aCtrl;
+
+public:
+ SbiAboutStarBasicDlg();
+};
+
+SbiAboutStarBasicDlg::SbiAboutStarBasicDlg() :
+ ModalDialog( GetpApp()->GetAppWindow(), BasicResId( RID_BASIC_START ) ),
+ aOkButton( this, BasicResId( 1 ) ),
+ aCtrl( this, BasicResId( 1 ) )
+{
+ FreeResource();
+}
+*/
+//-----------------------------------------------------------------------------------------
+
+RTLFUNC(AboutStarBasic)
+{
+ /*
+ String aName;
+ if( rPar.Count() >= 2 )
+ {
+ aName = rPar.Get(1)->GetString();
+ }
+
+ SbiAboutStarBasicDlg* pDlg = new SbiAboutStarBasicDlg;
+ pDlg->Execute();
+ delete pDlg;
+ */
+}
+
+// MsgBox( msg [,type[,title]] )
+
+RTLFUNC(MsgBox)
+{
+ static const WinBits nStyleMap[] =
+ {
+ WB_OK, // MB_OK
+ WB_OK_CANCEL, // MB_OKCANCEL
+ WB_RETRY_CANCEL, // MB_ABORTRETRYIGNORE
+ WB_YES_NO_CANCEL, // MB_YESNOCANCEL
+ WB_YES_NO, // MB_YESNO
+ WB_RETRY_CANCEL // MB_RETRYCANCEL
+ };
+ static const INT16 nButtonMap[] =
+ {
+ 2, // #define RET_CANCEL FALSE
+ 1, // #define RET_OK TRUE
+ 6, // #define RET_YES 2
+ 7, // #define RET_NO 3
+ 4 // #define RET_RETRY 4
+ };
+
+
+ USHORT nArgCount = (USHORT)rPar.Count();
+ if( nArgCount < 2 || nArgCount > 4 )
+ {
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ return;
+ }
+ WinBits nWinBits;
+ WinBits nType = 0; // MB_OK
+ if( nArgCount >= 3 )
+ nType = (WinBits)rPar.Get(2)->GetInteger();
+ WinBits nStyle = nType;
+ nStyle &= 15; // Bits 4-16 loeschen
+ if( nStyle > 5 )
+ nStyle = 0;
+
+ nWinBits = nStyleMap[ nStyle ];
+ if( nType & 4096 )
+ nWinBits |= WB_SYSMODAL;
+ if( nType & 256 )
+ {
+ if( nStyle == 5 || nStyle == 2)
+ nWinBits |= WB_DEF_CANCEL;
+ else
+ nWinBits |= (WB_DEF_CANCEL | WB_DEF_RETRY | WB_DEF_NO);
+ }
+ if( nType & 512 )
+ nWinBits |= WB_DEF_CANCEL;
+
+ String aMsg = rPar.Get(1)->GetString();
+ String aTitle;
+ if( nArgCount == 4 )
+ aTitle = rPar.Get(3)->GetString();
+ else
+ aTitle = GetpApp()->GetAppName();
+
+ nType &= (16+32+64);
+ MessBox* pBox = 0;
+ Window* pParent = GetpApp()->GetDefModalDialogParent();
+ switch( nType )
+ {
+ case 16:
+ pBox = new ErrorBox( pParent, nWinBits, aMsg );
+ break;
+ case 32:
+ pBox = new QueryBox( pParent, nWinBits, aMsg );
+ break;
+ case 48:
+ pBox = new WarningBox( pParent, nWinBits, aMsg );
+ break;
+ case 64:
+ pBox = new InfoBox( pParent, aMsg );
+ break;
+ default:
+ pBox = new MessBox( pParent, nWinBits, aTitle, aMsg );
+ }
+ pBox->SetText( aTitle );
+ USHORT nRet = (USHORT)pBox->Execute();
+ if( nRet == TRUE )
+ nRet = 1;
+ rPar.Get(0)->PutInteger( nButtonMap[ nRet ] );
+ delete pBox;
+}
+
+RTLFUNC(SetAttr) // JSM
+{
+ rPar.Get(0)->PutEmpty();
+ if ( rPar.Count() == 3 )
+ {
+ String aStr = rPar.Get(1)->GetString();
+ INT16 nFlags = rPar.Get(2)->GetInteger();
+
+ // <-- UCB
+ if( hasUno() )
+ {
+ Reference< XSimpleFileAccess > xSFI = getFileAccess();
+ if( xSFI.is() )
+ {
+ try
+ {
+ sal_Bool bReadOnly = (nFlags & 0x0001) != 0; // ATTR_READONLY
+ xSFI->setReadOnly( aStr, bReadOnly );
+ }
+ catch( Exception & )
+ {
+ StarBASIC::Error( ERRCODE_IO_GENERAL );
+ }
+ }
+ }
+ else
+ // --> UCB
+ {
+ // #57064 Bei virtuellen URLs den Real-Path extrahieren
+ DirEntry aEntry( aStr );
+ String aFile = aEntry.GetFull();
+ #ifdef WIN
+ int nErr = _dos_setfileattr( aFile.GetStr(),(unsigned ) nFlags );
+ if ( nErr )
+ {
+ if (errno == EACCES)
+ StarBASIC::Error( SbERR_ACCESS_DENIED );
+ else
+ StarBASIC::Error( SbERR_FILE_NOT_FOUND );
+ }
+ #endif
+ ByteString aByteFile( aFile, gsl_getSystemTextEncoding() );
+ #ifdef WNT
+ if (!SetFileAttributes (aByteFile.GetBuffer(),(DWORD)nFlags))
+ StarBASIC::Error(SbERR_FILE_NOT_FOUND);
+ #endif
+ #ifdef OS2
+ FILESTATUS3 aFileStatus;
+ APIRET rc = DosQueryPathInfo(aByteFile.GetBuffer(),1,
+ &aFileStatus,sizeof(FILESTATUS3));
+ if (!rc)
+ {
+ if (aFileStatus.attrFile != nFlags)
+ {
+ aFileStatus.attrFile = nFlags;
+ rc = DosSetPathInfo(aFile.GetStr(),1,
+ &aFileStatus,sizeof(FILESTATUS3),0);
+ if (rc)
+ StarBASIC::Error( SbERR_FILE_NOT_FOUND );
+ }
+ }
+ else
+ StarBASIC::Error( SbERR_FILE_NOT_FOUND );
+ #endif
+ }
+ }
+ else
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+}
+
+RTLFUNC(Reset) // JSM
+{
+ SbiIoSystem* pIO = pINST->GetIoSystem();
+ if (pIO)
+ pIO->CloseAll();
+}
+
+RTLFUNC(DumpAllObjects)
+{
+ USHORT nArgCount = (USHORT)rPar.Count();
+ if( nArgCount < 2 || nArgCount > 3 )
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+ else if( !pBasic )
+ StarBASIC::Error( SbERR_INTERNAL_ERROR );
+ else
+ {
+ SbxObject* p = pBasic;
+ while( p->GetParent() )
+ p = p->GetParent();
+ SvFileStream aStrm( rPar.Get( 1 )->GetString(),
+ STREAM_WRITE | STREAM_TRUNC );
+ p->Dump( aStrm, rPar.Get( 2 )->GetBool() );
+ aStrm.Close();
+ if( aStrm.GetError() != SVSTREAM_OK )
+ StarBASIC::Error( SbERR_IO_ERROR );
+ }
+}
+
+
+RTLFUNC(FileExists)
+{
+ if ( rPar.Count() == 2 )
+ {
+ String aStr = rPar.Get(1)->GetString();
+ BOOL bExists = FALSE;
+
+ // <-- UCB
+ if( hasUno() )
+ {
+ Reference< XSimpleFileAccess > xSFI = getFileAccess();
+ if( xSFI.is() )
+ {
+ try
+ {
+ bExists = xSFI->exists( aStr );
+ }
+ catch( Exception & )
+ {
+ StarBASIC::Error( ERRCODE_IO_GENERAL );
+ }
+ }
+ }
+ else
+ // --> UCB
+ {
+ DirEntry aEntry( aStr );
+ bExists = aEntry.Exists();
+ }
+ rPar.Get(0)->PutBool( bExists );
+ }
+ else
+ StarBASIC::Error( SbERR_BAD_ARGUMENT );
+}
+