LCOV - code coverage report
Current view: top level - basic/source/runtime - methods.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 443 2190 20.2 %
Date: 2015-06-13 12:38:46 Functions: 31 145 21.4 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11