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