diff options
Diffstat (limited to 'basic/source/runtime')
-rw-r--r-- | basic/source/runtime/basrdll.cxx | 9 | ||||
-rw-r--r-- | basic/source/runtime/comenumwrapper.cxx | 4 | ||||
-rw-r--r-- | basic/source/runtime/comenumwrapper.hxx | 5 | ||||
-rw-r--r-- | basic/source/runtime/ddectrl.cxx | 2 | ||||
-rw-r--r-- | basic/source/runtime/ddectrl.hxx | 2 | ||||
-rw-r--r-- | basic/source/runtime/dllmgr-none.cxx | 43 | ||||
-rw-r--r-- | basic/source/runtime/dllmgr-x64.cxx | 65 | ||||
-rw-r--r-- | basic/source/runtime/dllmgr-x86.cxx | 4 | ||||
-rw-r--r-- | basic/source/runtime/dllmgr.hxx | 6 | ||||
-rw-r--r-- | basic/source/runtime/inputbox.cxx | 16 | ||||
-rw-r--r-- | basic/source/runtime/iosys.cxx | 32 | ||||
-rw-r--r-- | basic/source/runtime/methods.cxx | 2787 | ||||
-rw-r--r-- | basic/source/runtime/methods1.cxx | 666 | ||||
-rw-r--r-- | basic/source/runtime/props.cxx | 105 | ||||
-rw-r--r-- | basic/source/runtime/runtime.cxx | 452 | ||||
-rw-r--r-- | basic/source/runtime/stdobj.cxx | 400 | ||||
-rw-r--r-- | basic/source/runtime/stdobj1.cxx | 78 |
17 files changed, 2087 insertions, 2589 deletions
diff --git a/basic/source/runtime/basrdll.cxx b/basic/source/runtime/basrdll.cxx index ba94fd7b9d2b..853863b4fcfd 100644 --- a/basic/source/runtime/basrdll.cxx +++ b/basic/source/runtime/basrdll.cxx @@ -37,12 +37,11 @@ struct BasicDLLImpl : public SvRefBase bool bDebugMode; bool bBreakEnabled; - std::unique_ptr<SbxAppData> xSbxAppData; + SbxAppData aSbxAppData; BasicDLLImpl() : bDebugMode(false) , bBreakEnabled(true) - , xSbxAppData(new SbxAppData) { } static BasicDLLImpl* BASIC_DLL; @@ -69,7 +68,7 @@ BasicDLL::~BasicDLL() std::scoped_lock aGuard(BasicDLLImpl::getMutex()); const bool bLastRef = m_xImpl->GetRefCount() == 1; if (bLastRef) { - BasicDLLImpl::BASIC_DLL->xSbxAppData->m_aGlobErr.clear(); + BasicDLLImpl::BASIC_DLL->aSbxAppData.m_aGlobErr.clear(); } m_xImpl.clear(); // only reset BASIC_DLL after the object had been destroyed @@ -122,12 +121,12 @@ void BasicDLL::BasicBreak() SbxAppData& GetSbxData_Impl() { - return *BasicDLLImpl::BASIC_DLL->xSbxAppData; + return BasicDLLImpl::BASIC_DLL->aSbxAppData; } bool IsSbxData_Impl() { - return BasicDLLImpl::BASIC_DLL && BasicDLLImpl::BASIC_DLL->xSbxAppData; + return BasicDLLImpl::BASIC_DLL; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/basic/source/runtime/comenumwrapper.cxx b/basic/source/runtime/comenumwrapper.cxx index b7881a1b9ade..2434197d76d8 100644 --- a/basic/source/runtime/comenumwrapper.cxx +++ b/basic/source/runtime/comenumwrapper.cxx @@ -30,7 +30,7 @@ sal_Bool SAL_CALL ComEnumerationWrapper::hasMoreElements() if ( m_xInvocation.is() ) { sal_Int32 nLength = 0; - bResult = ( ( m_xInvocation->getValue( "length" ) >>= nLength ) && nLength > m_nCurInd ); + bResult = ( ( m_xInvocation->getValue( u"length"_ustr ) >>= nLength ) && nLength > m_nCurInd ); } } catch(const uno::Exception& ) @@ -49,7 +49,7 @@ uno::Any SAL_CALL ComEnumerationWrapper::nextElement() uno::Sequence< uno::Any > aNamedParam; uno::Sequence< uno::Any > aArgs{ uno::Any(m_nCurInd++) }; - return m_xInvocation->invoke( "item", + return m_xInvocation->invoke( u"item"_ustr, aArgs, aNamedParamIndex, aNamedParam ); diff --git a/basic/source/runtime/comenumwrapper.hxx b/basic/source/runtime/comenumwrapper.hxx index 560829b331bb..38dd57f274a6 100644 --- a/basic/source/runtime/comenumwrapper.hxx +++ b/basic/source/runtime/comenumwrapper.hxx @@ -23,6 +23,7 @@ #include <com/sun/star/script/XInvocation.hpp> #include <cppuhelper/implbase.hxx> +#include <utility> class ComEnumerationWrapper : public ::cppu::WeakImplHelper<css::container::XEnumeration> { @@ -30,8 +31,8 @@ class ComEnumerationWrapper : public ::cppu::WeakImplHelper<css::container::XEnu sal_Int32 m_nCurInd; public: - explicit ComEnumerationWrapper(const css::uno::Reference<css::script::XInvocation>& xInvocation) - : m_xInvocation(xInvocation) + explicit ComEnumerationWrapper(css::uno::Reference<css::script::XInvocation> xInvocation) + : m_xInvocation(std::move(xInvocation)) , m_nCurInd(0) { } diff --git a/basic/source/runtime/ddectrl.cxx b/basic/source/runtime/ddectrl.cxx index bb2c4c5548f1..41e5c53d84de 100644 --- a/basic/source/runtime/ddectrl.cxx +++ b/basic/source/runtime/ddectrl.cxx @@ -17,7 +17,7 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ -#include <vcl/errcode.hxx> +#include <comphelper/errcode.hxx> #include <svl/svdde.hxx> #include "ddectrl.hxx" #include <basic/sberrors.hxx> diff --git a/basic/source/runtime/ddectrl.hxx b/basic/source/runtime/ddectrl.hxx index 3b4f3d9bb122..d341bbcb8e72 100644 --- a/basic/source/runtime/ddectrl.hxx +++ b/basic/source/runtime/ddectrl.hxx @@ -20,7 +20,7 @@ #pragma once #include <tools/link.hxx> -#include <vcl/errcode.hxx> +#include <comphelper/errcode.hxx> #include <memory> #include <vector> diff --git a/basic/source/runtime/dllmgr-none.cxx b/basic/source/runtime/dllmgr-none.cxx index 30070977d215..2a03e2ae7855 100644 --- a/basic/source/runtime/dllmgr-none.cxx +++ b/basic/source/runtime/dllmgr-none.cxx @@ -50,27 +50,26 @@ ErrCode returnInt64InOutArg(SbxArray *pArgs, SbxVariable &rRetVal, pOut->PutCurrency(nValue); return ERRCODE_NONE; } - if (pOut->IsObject()) - { - // FIXME: should we clone this and use pOut->PutObject ? - SbxObject* pObj = dynamic_cast<SbxObject*>( pOut->GetObject() ); - if (!pObj) - return ERRCODE_BASIC_BAD_ARGUMENT; - - // We expect two Longs but other mappings could be possible too. - SbxArray* pProps = pObj->GetProperties(); - if (pProps->Count() != 2) - return ERRCODE_BASIC_BAD_ARGUMENT; - SbxVariable* pLow = pProps->Get(0); - SbxVariable* pHigh = pProps->Get(1); - if (!pLow || !pLow->IsLong() || - !pHigh || !pHigh->IsLong()) - return ERRCODE_BASIC_BAD_ARGUMENT; - pLow->PutLong(nValue & 0xffffffff); - pHigh->PutLong(nValue >> 32); - return ERRCODE_NONE; - } - return ERRCODE_BASIC_BAD_ARGUMENT; + if (!pOut->IsObject()) + return ERRCODE_BASIC_BAD_ARGUMENT; + + // FIXME: should we clone this and use pOut->PutObject ? + SbxObject* pObj = dynamic_cast<SbxObject*>( pOut->GetObject() ); + if (!pObj) + return ERRCODE_BASIC_BAD_ARGUMENT; + + // We expect two Longs but other mappings could be possible too. + SbxArray* pProps = pObj->GetProperties(); + if (pProps->Count() != 2) + return ERRCODE_BASIC_BAD_ARGUMENT; + SbxVariable* pLow = pProps->Get(0); + SbxVariable* pHigh = pProps->Get(1); + if (!pLow || !pLow->IsLong() || + !pHigh || !pHigh->IsLong()) + return ERRCODE_BASIC_BAD_ARGUMENT; + pLow->PutLong(nValue & 0xffffffff); + pHigh->PutLong(nValue >> 32); + return ERRCODE_NONE; } ErrCode builtin_kernel32(std::u16string_view aFuncName, SbxArray *pArgs, @@ -107,6 +106,8 @@ void SbiDllMgr::FreeDll(SAL_UNUSED_PARAMETER OUString const &) {} SbiDllMgr::SbiDllMgr() = default; +#if defined(_WIN32) SbiDllMgr::~SbiDllMgr() = default; +#endif /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/basic/source/runtime/dllmgr-x64.cxx b/basic/source/runtime/dllmgr-x64.cxx index dad4bea8794a..ec5f79c4ab3e 100644 --- a/basic/source/runtime/dllmgr-x64.cxx +++ b/basic/source/runtime/dllmgr-x64.cxx @@ -27,10 +27,12 @@ #include <algorithm> #include <cstddef> #include <map> +#include <string_view> #include <vector> #include <basic/sbx.hxx> #include <basic/sbxvar.hxx> +#include <comphelper/string.hxx> #include <runtime.hxx> #include <osl/thread.h> #include <osl/diagnose.h> @@ -40,6 +42,7 @@ #include <sal/log.hxx> #include <salhelper/simplereferenceobject.hxx> #include <o3tl/char16_t2wchar_t.hxx> +#include <o3tl/string_view.hxx> #undef max @@ -481,7 +484,7 @@ struct ProcData { }; ErrCode call( - OUString const & dll, ProcData const & proc, SbxArray * arguments, + std::u16string_view dll, ProcData const & proc, SbxArray * arguments, SbxVariable & result) { if (arguments && arguments->Count() > 20) @@ -495,7 +498,7 @@ ErrCode call( // requires special handling in unmarshalString; other functions might // require similar treatment, too: bool special = - dll.equalsIgnoreAsciiCase("KERNEL32.DLL") && + o3tl::equalsIgnoreAsciiCase(dll, u"KERNEL32.DLL") && (proc.name == "GetLogicalDriveStringsA"); for (sal_uInt32 i = 1; i < (arguments == nullptr ? 0 : arguments->Count()); ++i) { @@ -512,8 +515,6 @@ ErrCode call( // We fake all calls as being to a varargs function, // as this means any floating-point argument among the first four // ones will end up in a XMM register where the callee expects it. - sal_Int32 (*proc_i)(double d, ...) = reinterpret_cast<sal_Int32 (*)(double, ...)>(proc.proc); - double (*proc_d)(double d, ...) = reinterpret_cast<double (*)(double, ...)>(proc.proc); sal_Int64 iRetVal = 0; double dRetVal = 0.0; @@ -527,55 +528,21 @@ ErrCode call( case SbxBOOL: case SbxBYTE: { - auto const st = stack.data(); - iRetVal = - proc_i(*reinterpret_cast<double *>(st + 0), - *reinterpret_cast<double *>(st + 1*8), - *reinterpret_cast<double *>(st + 2*8), - *reinterpret_cast<double *>(st + 3*8), - *reinterpret_cast<sal_uInt64 *>(st + 4*8), - *reinterpret_cast<sal_uInt64 *>(st + 5*8), - *reinterpret_cast<sal_uInt64 *>(st + 6*8), - *reinterpret_cast<sal_uInt64 *>(st + 7*8), - *reinterpret_cast<sal_uInt64 *>(st + 8*8), - *reinterpret_cast<sal_uInt64 *>(st + 9*8), - *reinterpret_cast<sal_uInt64 *>(st + 10*8), - *reinterpret_cast<sal_uInt64 *>(st + 11*8), - *reinterpret_cast<sal_uInt64 *>(st + 12*8), - *reinterpret_cast<sal_uInt64 *>(st + 13*8), - *reinterpret_cast<sal_uInt64 *>(st + 14*8), - *reinterpret_cast<sal_uInt64 *>(st + 15*8), - *reinterpret_cast<sal_uInt64 *>(st + 16*8), - *reinterpret_cast<sal_uInt64 *>(st + 17*8), - *reinterpret_cast<sal_uInt64 *>(st + 18*8), - *reinterpret_cast<sal_uInt64 *>(st + 19*8)); + auto p = reinterpret_cast<sal_Int64 (*)(...)>(proc.proc); + auto const st = reinterpret_cast<double *>(stack.data()); + iRetVal + = p(st[0], st[1], st[2], st[3], st[4], st[5], st[6], st[7], st[8], st[9], st[10], + st[11], st[12], st[13], st[14], st[15], st[16], st[17], st[18], st[19]); break; } case SbxSINGLE: case SbxDOUBLE: { - auto const st = stack.data(); - dRetVal = - proc_d(*reinterpret_cast<double *>(st + 0), - *reinterpret_cast<double *>(st + 1*8), - *reinterpret_cast<double *>(st + 2*8), - *reinterpret_cast<double *>(st + 3*8), - *reinterpret_cast<sal_uInt64 *>(st + 4*8), - *reinterpret_cast<sal_uInt64 *>(st + 5*8), - *reinterpret_cast<sal_uInt64 *>(st + 6*8), - *reinterpret_cast<sal_uInt64 *>(st + 7*8), - *reinterpret_cast<sal_uInt64 *>(st + 8*8), - *reinterpret_cast<sal_uInt64 *>(st + 9*8), - *reinterpret_cast<sal_uInt64 *>(st + 10*8), - *reinterpret_cast<sal_uInt64 *>(st + 11*8), - *reinterpret_cast<sal_uInt64 *>(st + 12*8), - *reinterpret_cast<sal_uInt64 *>(st + 13*8), - *reinterpret_cast<sal_uInt64 *>(st + 14*8), - *reinterpret_cast<sal_uInt64 *>(st + 15*8), - *reinterpret_cast<sal_uInt64 *>(st + 16*8), - *reinterpret_cast<sal_uInt64 *>(st + 17*8), - *reinterpret_cast<sal_uInt64 *>(st + 18*8), - *reinterpret_cast<sal_uInt64 *>(st + 19*8)); + auto p = reinterpret_cast<double (*)(...)>(proc.proc); + auto const st = reinterpret_cast<double*>(stack.data()); + dRetVal + = p(st[0], st[1], st[2], st[3], st[4], st[5], st[6], st[7], st[8], st[9], st[10], + st[11], st[12], st[13], st[14], st[15], st[16], st[17], st[18], st[19]); break; } default: @@ -644,7 +611,7 @@ ErrCode getProcData(HMODULE handle, OUString const & name, ProcData * proc) { assert(proc != nullptr); if (name.getLength() != 0 && name[0] == '@') { //TODO: "@" vs. "#"??? - sal_Int32 n = name.copy(1).toInt32(); //TODO: handle bad input + sal_IntPtr n = o3tl::toInt32(name.subView(1)); //TODO: handle bad input if (n <= 0 || n > 0xFFFF) { return ERRCODE_BASIC_BAD_ARGUMENT; //TODO: more specific errcode? } diff --git a/basic/source/runtime/dllmgr-x86.cxx b/basic/source/runtime/dllmgr-x86.cxx index 93e5c2bf533f..7ab84d7f8b56 100644 --- a/basic/source/runtime/dllmgr-x86.cxx +++ b/basic/source/runtime/dllmgr-x86.cxx @@ -31,6 +31,7 @@ #include <basic/sbx.hxx> #include <basic/sbxvar.hxx> +#include <comphelper/string.hxx> #include "runtime.hxx" #include <osl/thread.h> #include <rtl/ref.hxx> @@ -39,6 +40,7 @@ #include <sal/log.hxx> #include <salhelper/simplereferenceobject.hxx> #include <o3tl/char16_t2wchar_t.hxx> +#include <o3tl/string_view.hxx> #undef max @@ -584,7 +586,7 @@ ErrCode getProcData(HMODULE handle, OUString const & name, ProcData * proc) { assert(proc != 0); if ( !name.isEmpty() && name[0] == '@' ) { //TODO: "@" vs. "#"??? - sal_Int32 n = name.copy(1).toInt32(); //TODO: handle bad input + sal_Int32 n = o3tl::toInt32(name.subView(1)); //TODO: handle bad input if (n <= 0 || n > 0xFFFF) { return ERRCODE_BASIC_BAD_ARGUMENT; //TODO: more specific errcode? } diff --git a/basic/source/runtime/dllmgr.hxx b/basic/source/runtime/dllmgr.hxx index 3f984c95105c..fe76cfb681b6 100644 --- a/basic/source/runtime/dllmgr.hxx +++ b/basic/source/runtime/dllmgr.hxx @@ -20,7 +20,7 @@ #pragma once #include <sal/config.h> -#include <vcl/errcode.hxx> +#include <comphelper/errcode.hxx> #include <memory> class SbxArray; @@ -33,7 +33,9 @@ public: SbiDllMgr(); +#if defined(_WIN32) ~SbiDllMgr(); +#endif ErrCode Call( std::u16string_view function, std::u16string_view library, @@ -42,7 +44,7 @@ public: void FreeDll(OUString const & library); private: -#if defined(_WIN32) && !defined(_ARM64_) +#if defined(_WIN32) struct Impl; std::unique_ptr< Impl > impl_; diff --git a/basic/source/runtime/inputbox.cxx b/basic/source/runtime/inputbox.cxx index 36d604298bad..5f55aceb98b3 100644 --- a/basic/source/runtime/inputbox.cxx +++ b/basic/source/runtime/inputbox.cxx @@ -19,9 +19,9 @@ #include <basic/sberrors.hxx> #include <tools/lineend.hxx> +#include <vcl/outdev.hxx> #include <vcl/svapp.hxx> #include <vcl/weld.hxx> -#include <vcl/window.hxx> #include <rtlproto.hxx> #include <memory> @@ -52,11 +52,11 @@ public: SvRTLInputBox::SvRTLInputBox(weld::Window* pParent, const OUString& rPrompt, const OUString& rTitle, const OUString& rDefault, tools::Long nXTwips, tools::Long nYTwips) - : GenericDialogController(pParent, "svt/ui/inputbox.ui", "InputBox") - , m_xEdit(m_xBuilder->weld_entry("entry")) - , m_xOk(m_xBuilder->weld_button("ok")) - , m_xCancel(m_xBuilder->weld_button("cancel")) - , m_xPromptText(m_xBuilder->weld_label("prompt")) + : GenericDialogController(pParent, u"svt/ui/inputbox.ui"_ustr, u"InputBox"_ustr) + , m_xEdit(m_xBuilder->weld_entry(u"entry"_ustr)) + , m_xOk(m_xBuilder->weld_button(u"ok"_ustr)) + , m_xCancel(m_xBuilder->weld_button(u"cancel"_ustr)) + , m_xPromptText(m_xBuilder->weld_label(u"prompt"_ustr)) { PositionDialog( nXTwips, nYTwips ); InitButtons(); @@ -118,7 +118,7 @@ void SbRtl_InputBox(StarBASIC *, SbxArray & rPar, bool) OUString aTitle; OUString aDefault; sal_Int32 nX = -1, nY = -1; // center - const OUString& rPrompt = rPar.Get(1)->GetOUString(); + const OUString aPrompt = rPar.Get(1)->GetOUString(); if (nArgCount > 2 && !rPar.Get(2)->IsErr()) aTitle = rPar.Get(2)->GetOUString(); if (nArgCount > 3 && !rPar.Get(3)->IsErr()) @@ -133,7 +133,7 @@ void SbRtl_InputBox(StarBASIC *, SbxArray & rPar, bool) nX = rPar.Get(4)->GetLong(); nY = rPar.Get(5)->GetLong(); } - SvRTLInputBox aDlg(Application::GetDefDialogParent(), rPrompt, aTitle, aDefault, nX, nY); + SvRTLInputBox aDlg(Application::GetDefDialogParent(), aPrompt, aTitle, aDefault, nX, nY); aDlg.run(); rPar.Get(0)->PutString(aDlg.GetText()); } diff --git a/basic/source/runtime/iosys.cxx b/basic/source/runtime/iosys.cxx index 43ee1c4d6856..a30f8e763aff 100644 --- a/basic/source/runtime/iosys.cxx +++ b/basic/source/runtime/iosys.cxx @@ -20,7 +20,7 @@ #include <string.h> #include <vcl/svapp.hxx> #include <vcl/weld.hxx> -#include <vcl/window.hxx> +#include <osl/diagnose.h> #include <osl/file.hxx> #include <runtime.hxx> @@ -38,14 +38,12 @@ #include <com/sun/star/io/XOutputStream.hpp> #include <com/sun/star/io/XStream.hpp> #include <com/sun/star/io/XSeekable.hpp> +#include <iosys.hxx> using namespace com::sun::star::uno; -using namespace com::sun::star::lang; using namespace com::sun::star::ucb; using namespace com::sun::star::io; -using namespace com::sun::star::bridge; -#include <iosys.hxx> namespace { @@ -66,11 +64,11 @@ public: } SbiInputDialog::SbiInputDialog(weld::Window* pParent, const OUString& rPrompt) - : GenericDialogController(pParent, "svt/ui/inputbox.ui", "InputBox") - , m_xInput(m_xBuilder->weld_entry("entry")) - , m_xOk(m_xBuilder->weld_button("ok")) - , m_xCancel(m_xBuilder->weld_button("cancel")) - , m_xPromptText(m_xBuilder->weld_label("prompt")) + : GenericDialogController(pParent, u"svt/ui/inputbox.ui"_ustr, u"InputBox"_ustr) + , m_xInput(m_xBuilder->weld_entry(u"entry"_ustr)) + , m_xOk(m_xBuilder->weld_button(u"ok"_ustr)) + , m_xCancel(m_xBuilder->weld_button(u"cancel"_ustr)) + , m_xPromptText(m_xBuilder->weld_label(u"prompt"_ustr)) { m_xDialog->set_title(rPrompt); m_xPromptText->set_label(rPrompt); @@ -134,7 +132,7 @@ void SbiStream::MapError() bool hasUno() { static const bool bRetVal = [] { - Reference< XComponentContext > xContext = comphelper::getProcessComponentContext(); + const Reference< XComponentContext >& xContext = comphelper::getProcessComponentContext(); if( !xContext.is() ) { // No service manager at all @@ -144,7 +142,7 @@ bool hasUno() { Reference< XUniversalContentBroker > xManager = UniversalContentBroker::create(xContext); - if ( !( xManager->queryContentProvider( "file:///" ).is() ) ) + if ( !( xManager->queryContentProvider( u"file:///"_ustr ).is() ) ) { // No UCB return false; @@ -417,7 +415,7 @@ void UCBStream::SetSize( sal_uInt64 ) ErrCode const & SbiStream::Open -( std::string_view rName, StreamMode nStrmMode, SbiStreamFlags nFlags, short nL ) +( const OUString& rName, StreamMode nStrmMode, SbiStreamFlags nFlags, short nL ) { nMode = nFlags; nLen = nL; @@ -427,8 +425,7 @@ ErrCode const & SbiStream::Open { nStrmMode |= StreamMode::NOCREATE; } - OUString aStr(OStringToOUString(rName, osl_getThreadTextEncoding())); - OUString aNameStr = getFullPath( aStr ); + OUString aNameStr = getFullPath(rName); if( hasUno() ) { @@ -563,7 +560,7 @@ namespace void WriteLines(SvStream &rStream, const OString& rStr) { OString aStr(convertLineEnd(rStr, rStream.GetLineDelimiter()) ); - write_uInt8s_FromOString(rStream, aStr); + rStream.WriteBytes(aStr.getStr(), aStr.getLength()); endl( rStream ); } } @@ -627,7 +624,7 @@ ErrCode SbiIoSystem::GetError() return n; } -void SbiIoSystem::Open(short nCh, std::string_view rName, StreamMode nMode, SbiStreamFlags nFlags, short nLen) +void SbiIoSystem::Open(short nCh, const OUString& rName, StreamMode nMode, SbiStreamFlags nFlags, short nLen) { nError = ERRCODE_NONE; if( nCh >= CHANNELS || !nCh ) @@ -786,8 +783,7 @@ void SbiIoSystem::CloseAll() void SbiIoSystem::ReadCon(OString& rIn) { - OUString aPromptStr(OStringToOUString(aPrompt, osl_getThreadTextEncoding())); - SbiInputDialog aDlg(nullptr, aPromptStr); + SbiInputDialog aDlg(nullptr, aPrompt); if (aDlg.run() == RET_OK) { rIn = OUStringToOString(aDlg.GetInput(), osl_getThreadTextEncoding()); diff --git a/basic/source/runtime/methods.cxx b/basic/source/runtime/methods.cxx index 7e9a1adcccd7..679414e10a14 100644 --- a/basic/source/runtime/methods.cxx +++ b/basic/source/runtime/methods.cxx @@ -24,11 +24,10 @@ #include <basic/sbuno.hxx> #include <osl/process.h> #include <vcl/dibtools.hxx> -#include <vcl/window.hxx> #include <vcl/svapp.hxx> #include <vcl/settings.hxx> #include <vcl/sound.hxx> -#include <tools/wintypes.hxx> +#include <vcl/wintypes.hxx> #include <vcl/stdtext.hxx> #include <vcl/weld.hxx> #include <basic/sbx.hxx> @@ -45,6 +44,7 @@ #include <rtl/string.hxx> #include <sal/log.hxx> #include <comphelper/DirectoryHelper.hxx> +#include <comphelper/lok.hxx> #include <runtime.hxx> #include <sbunoobj.hxx> @@ -60,6 +60,7 @@ #include <com/sun/star/lang/XServiceInfo.hpp> #include <com/sun/star/ucb/SimpleFileAccess.hpp> #include <com/sun/star/script/XErrorQuery.hpp> +#include <ooo/vba/VbStrConv.hpp> #include <ooo/vba/VbTriState.hpp> #include <com/sun/star/bridge/oleautomation/XAutomationObject.hpp> #include <memory> @@ -68,20 +69,12 @@ #include <o3tl/char16_t2wchar_t.hxx> // include search util -#include <com/sun/star/util/SearchFlags.hpp> +#include <com/sun/star/i18n/Transliteration.hpp> #include <com/sun/star/util/SearchAlgorithms2.hpp> #include <i18nutil/searchopt.hxx> #include <unotools/textsearch.hxx> #include <svl/numformat.hxx> - - -using namespace comphelper; -using namespace osl; -using namespace com::sun::star; -using namespace com::sun::star::lang; -using namespace com::sun::star::uno; - #include <date.hxx> #include <sbstdobj.hxx> #include <rtlproto.hxx> @@ -109,12 +102,24 @@ using namespace com::sun::star::uno; #include <unistd.h> #endif -#include <com/sun/star/i18n/XCharacterClassification.hpp> -#include <vcl/unohelp.hxx> #include <vcl/TypeSerializer.hxx> +using namespace comphelper; +using namespace osl; +using namespace com::sun::star; +using namespace com::sun::star::lang; +using namespace com::sun::star::uno; + +static sal_Int32 GetDayDiff(const Date& rDate) { return rDate - Date(1899'12'30); } + #if HAVE_FEATURE_SCRIPTING +static sal_Int32 nanoSecToMilliSec(sal_Int64 nNanoSeconds) +{ + // Rounding nanoseconds to milliseconds precision to avoid comparison inaccuracies + return o3tl::convert(nNanoSeconds, 1, tools::Time::nanoPerMilli); +} + static void FilterWhiteSpace( OUString& rStr ) { if (rStr.isEmpty()) @@ -136,8 +141,6 @@ static void FilterWhiteSpace( OUString& rStr ) rStr = aRet.makeStringAndClear(); } -static tools::Long GetDayDiff( const Date& rDate ); - static const CharClass& GetCharClass() { static CharClass aCharClass( Application::GetSettings().GetLanguageTag() ); @@ -185,16 +188,17 @@ static uno::Reference< ucb::XSimpleFileAccess3 > const & getFileAccess() void SbRtl_CreateObject(StarBASIC * pBasic, SbxArray & rPar, bool) { + if( rPar.Count() < 2 ) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + OUString aClass(rPar.Get(1)->GetOUString()); SbxObjectRef p = SbxBase::CreateObject( aClass ); if( !p.is() ) - StarBASIC::Error( ERRCODE_BASIC_CANNOT_LOAD ); - else - { - // Convenience: enter BASIC as parent - p->SetParent( pBasic ); - rPar.Get(0)->PutObject(p.get()); - } + return StarBASIC::Error( ERRCODE_BASIC_CANNOT_LOAD ); + + // Convenience: enter BASIC as parent + p->SetParent( pBasic ); + rPar.Get(0)->PutObject(p.get()); } // Error( n ) @@ -202,54 +206,51 @@ void SbRtl_CreateObject(StarBASIC * pBasic, SbxArray & rPar, bool) void SbRtl_Error(StarBASIC * pBasic, SbxArray & rPar, bool) { if( !pBasic ) - StarBASIC::Error( ERRCODE_BASIC_INTERNAL_ERROR ); + return StarBASIC::Error( ERRCODE_BASIC_INTERNAL_ERROR ); + + OUString aErrorMsg; + ErrCode nErr = ERRCODE_NONE; + sal_Int32 nCode = 0; + if (rPar.Count() == 1) + { + nErr = StarBASIC::GetErrBasic(); + aErrorMsg = StarBASIC::GetErrorMsg(); + } else { - OUString aErrorMsg; - ErrCode nErr = ERRCODE_NONE; - sal_Int32 nCode = 0; - if (rPar.Count() == 1) + nCode = rPar.Get(1)->GetLong(); + if( nCode > 65535 ) { - nErr = StarBASIC::GetErrBasic(); - aErrorMsg = StarBASIC::GetErrorMsg(); - } - else - { - nCode = rPar.Get(1)->GetLong(); - if( nCode > 65535 ) - { - StarBASIC::Error( ERRCODE_BASIC_CONVERSION ); - } - else - { - nErr = StarBASIC::GetSfxFromVBError( static_cast<sal_uInt16>(nCode) ); - } - } - - bool bVBA = SbiRuntime::isVBAEnabled(); - OUString tmpErrMsg; - if( bVBA && !aErrorMsg.isEmpty()) - { - tmpErrMsg = aErrorMsg; + StarBASIC::Error( ERRCODE_BASIC_CONVERSION ); } else { - StarBASIC::MakeErrorText( nErr, aErrorMsg ); - tmpErrMsg = StarBASIC::GetErrorText(); + nErr = StarBASIC::GetSfxFromVBError( static_cast<sal_uInt16>(nCode) ); } - // If this rtlfunc 'Error' passed an errcode the same as the active Err Objects's - // current err then return the description for the error message if it is set - // ( complicated isn't it ? ) - if (bVBA && rPar.Count() > 1) + } + bool bVBA = SbiRuntime::isVBAEnabled(); + OUString tmpErrMsg; + if( bVBA && !aErrorMsg.isEmpty()) + { + tmpErrMsg = aErrorMsg; + } + else + { + StarBASIC::MakeErrorText( nErr, aErrorMsg ); + tmpErrMsg = StarBASIC::GetErrorText(); + } + // If this rtlfunc 'Error' passed an errcode the same as the active Err Objects's + // current err then return the description for the error message if it is set + // ( complicated isn't it ? ) + if (bVBA && rPar.Count() > 1) + { + uno::Reference< ooo::vba::XErrObject > xErrObj( SbxErrObject::getUnoErrObject() ); + if ( xErrObj.is() && xErrObj->getNumber() == nCode && !xErrObj->getDescription().isEmpty() ) { - uno::Reference< ooo::vba::XErrObject > xErrObj( SbxErrObject::getUnoErrObject() ); - if ( xErrObj.is() && xErrObj->getNumber() == nCode && !xErrObj->getDescription().isEmpty() ) - { - tmpErrMsg = xErrObj->getDescription(); - } + tmpErrMsg = xErrObj->getDescription(); } - rPar.Get(0)->PutString(tmpErrMsg); } + rPar.Get(0)->PutString(tmpErrMsg); } // Sinus @@ -257,106 +258,87 @@ void SbRtl_Error(StarBASIC * pBasic, SbxArray & rPar, bool) void SbRtl_Sin(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() < 2) - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - else - { - SbxVariableRef pArg = rPar.Get(1); - rPar.Get(0)->PutDouble(sin(pArg->GetDouble())); - } + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + SbxVariableRef pArg = rPar.Get(1); + rPar.Get(0)->PutDouble(sin(pArg->GetDouble())); } void SbRtl_Cos(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() < 2) - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - else - { - SbxVariableRef pArg = rPar.Get(1); - rPar.Get(0)->PutDouble(cos(pArg->GetDouble())); - } + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + SbxVariableRef pArg = rPar.Get(1); + rPar.Get(0)->PutDouble(cos(pArg->GetDouble())); } void SbRtl_Atn(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() < 2) - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - else - { - SbxVariableRef pArg = rPar.Get(1); - rPar.Get(0)->PutDouble(atan(pArg->GetDouble())); - } + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + SbxVariableRef pArg = rPar.Get(1); + rPar.Get(0)->PutDouble(atan(pArg->GetDouble())); } void SbRtl_Abs(StarBASIC *, SbxArray & rPar, bool) { - if (rPar.Count() < 2) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } - else - { - SbxVariableRef pArg = rPar.Get(1); - rPar.Get(0)->PutDouble(fabs(pArg->GetDouble())); - } + if (rPar.Count() != 2) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + SbxVariableRef pArg = rPar.Get(1); + rPar.Get(0)->PutDouble(fabs(pArg->GetDouble())); } void SbRtl_Asc(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() < 2) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + SbxVariableRef pArg = rPar.Get(1); + OUString aStr( pArg->GetOUString() ); + if ( aStr.isEmpty()) { StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + rPar.Get(0)->PutEmpty(); + return; } - else - { - SbxVariableRef pArg = rPar.Get(1); - OUString aStr( pArg->GetOUString() ); - if ( aStr.isEmpty()) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - rPar.Get(0)->PutEmpty(); - } - else - { - sal_Unicode aCh = aStr[0]; - rPar.Get(0)->PutLong(aCh); - } - } + sal_Unicode aCh = aStr[0]; + rPar.Get(0)->PutLong(aCh); } static void implChr( SbxArray& rPar, bool bChrW ) { if (rPar.Count() < 2) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + SbxVariableRef pArg = rPar.Get(1); + + OUString aStr; + if( !bChrW && SbiRuntime::isVBAEnabled() ) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + char c = static_cast<char>(pArg->GetByte()); + aStr = OUString(&c, 1, osl_getThreadTextEncoding()); } else { - SbxVariableRef pArg = rPar.Get(1); - - OUString aStr; - if( !bChrW && SbiRuntime::isVBAEnabled() ) - { - char c = static_cast<char>(pArg->GetByte()); - aStr = OUString(&c, 1, osl_getThreadTextEncoding()); - } - else + // Map negative 16-bit values to large positive ones, so that code like Chr(&H8000) + // still works after the fix for tdf#62326 changed those four-digit hex notations to + // produce negative values: + sal_Int32 aCh = pArg->GetLong(); + if (aCh < -0x8000 || aCh > 0xFFFF) { - // Map negative 16-bit values to large positive ones, so that code like Chr(&H8000) - // still works after the fix for tdf#62326 changed those four-digit hex notations to - // produce negative values: - sal_Int32 aCh = pArg->GetLong(); - if (aCh < -0x8000 || aCh > 0xFFFF) { - StarBASIC::Error(ERRCODE_BASIC_MATH_OVERFLOW); - aCh = 0; - } - aStr = OUString(static_cast<sal_Unicode>(aCh)); + StarBASIC::Error(ERRCODE_BASIC_MATH_OVERFLOW); + aCh = 0; } - rPar.Get(0)->PutString(aStr); + aStr = OUString(static_cast<sal_Unicode>(aCh)); } + rPar.Get(0)->PutString(aStr); } void SbRtl_Chr(StarBASIC *, SbxArray & rPar, bool) @@ -396,22 +378,21 @@ void SbRtl_CurDir(StarBASIC *, SbxArray & rPar, bool) // there's no possibility to detect the current one in a way that a virtual URL // could be delivered. + if (rPar.Count() > 2) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + #if defined(_WIN32) int nCurDir = 0; // Current dir // JSM if (rPar.Count() == 2) { OUString aDrive = rPar.Get(1)->GetOUString(); if ( aDrive.getLength() != 1 ) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; - } + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + auto c = rtl::toAsciiUpperCase(aDrive[0]); if ( !rtl::isAsciiUpperCase( c ) ) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; - } + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + nCurDir = c - 'A' + 1; } wchar_t pBuffer[ _MAX_PATH ]; @@ -421,14 +402,10 @@ void SbRtl_CurDir(StarBASIC *, SbxArray & rPar, bool) auto const handler = _set_thread_local_invalid_parameter_handler(&invalidParameterHandler); auto const ok = _wgetdcwd( nCurDir, pBuffer, _MAX_PATH ) != nullptr; _set_thread_local_invalid_parameter_handler(handler); - if ( ok ) - { - rPar.Get(0)->PutString(OUString(o3tl::toU(pBuffer))); - } - else - { - StarBASIC::Error( ERRCODE_BASIC_NO_DEVICE ); - } + if ( !ok ) + return StarBASIC::Error( ERRCODE_BASIC_NO_DEVICE ); + + rPar.Get(0)->PutString(OUString(o3tl::toU(pBuffer))); #else @@ -440,20 +417,16 @@ void SbRtl_CurDir(StarBASIC *, SbxArray & rPar, bool) { pMem.reset(new char[nSize]); if( !pMem ) - { - StarBASIC::Error( ERRCODE_BASIC_NO_MEMORY ); - return; - } + return StarBASIC::Error( ERRCODE_BASIC_NO_MEMORY ); + if( getcwd( pMem.get(), nSize-1 ) != nullptr ) { rPar.Get(0)->PutString(OUString::createFromAscii(pMem.get())); return; } if( errno != ERANGE ) - { - StarBASIC::Error( ERRCODE_BASIC_INTERNAL_ERROR ); - return; - } + return StarBASIC::Error( ERRCODE_BASIC_INTERNAL_ERROR ); + nSize += PATH_INCR; }; @@ -463,18 +436,14 @@ void SbRtl_CurDir(StarBASIC *, SbxArray & rPar, bool) void SbRtl_ChDir(StarBASIC * pBasic, SbxArray & rPar, bool) { rPar.Get(0)->PutEmpty(); - if (rPar.Count() == 2) - { - // VBA: track current directory per document type (separately for Writer, Calc, Impress, etc.) - if( SbiRuntime::isVBAEnabled() ) - { - ::basic::vba::registerCurrentDirectory(getDocumentModel(pBasic), - rPar.Get(1)->GetOUString()); - } - } - else + if (rPar.Count() != 2) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + // VBA: track current directory per document type (separately for Writer, Calc, Impress, etc.) + if( SbiRuntime::isVBAEnabled() ) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + ::basic::vba::registerCurrentDirectory(getDocumentModel(pBasic), + rPar.Get(1)->GetOUString()); } } @@ -482,9 +451,7 @@ void SbRtl_ChDrive(StarBASIC *, SbxArray & rPar, bool) { rPar.Get(0)->PutEmpty(); if (rPar.Count() != 2) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); } @@ -533,129 +500,119 @@ void implStepRenameOSL( const OUString& aSource, const OUString& aDest ) void SbRtl_FileCopy(StarBASIC *, SbxArray & rPar, bool) { rPar.Get(0)->PutEmpty(); - if (rPar.Count() == 3) + if (rPar.Count() != 3) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + OUString aSource = rPar.Get(1)->GetOUString(); + OUString aDest = rPar.Get(2)->GetOUString(); + if( hasUno() ) { - OUString aSource = rPar.Get(1)->GetOUString(); - OUString aDest = rPar.Get(2)->GetOUString(); - if( hasUno() ) + const uno::Reference< ucb::XSimpleFileAccess3 >& xSFI = getFileAccess(); + if( xSFI.is() ) { - const uno::Reference< ucb::XSimpleFileAccess3 >& xSFI = getFileAccess(); - if( xSFI.is() ) + try { - try - { - xSFI->copy( getFullPath( aSource ), getFullPath( aDest ) ); - } - catch(const Exception & ) - { - StarBASIC::Error( ERRCODE_BASIC_PATH_NOT_FOUND ); - } + xSFI->copy( getFullPath( aSource ), getFullPath( aDest ) ); } - } - else - { - FileBase::RC nRet = File::copy( getFullPath( aSource ), getFullPath( aDest ) ); - if( nRet != FileBase::E_None ) + catch(const Exception & ) { StarBASIC::Error( ERRCODE_BASIC_PATH_NOT_FOUND ); } } } else - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + { + FileBase::RC nRet = File::copy( getFullPath( aSource ), getFullPath( aDest ) ); + if( nRet != FileBase::E_None ) + { + StarBASIC::Error( ERRCODE_BASIC_PATH_NOT_FOUND ); + } + } } void SbRtl_Kill(StarBASIC *, SbxArray & rPar, bool) { rPar.Get(0)->PutEmpty(); - if (rPar.Count() == 2) - { - OUString aFileSpec = rPar.Get(1)->GetOUString(); + if (rPar.Count() != 2) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - if( hasUno() ) + OUString aFileSpec = rPar.Get(1)->GetOUString(); + + if( hasUno() ) + { + const uno::Reference< ucb::XSimpleFileAccess3 >& xSFI = getFileAccess(); + if( xSFI.is() ) { - const uno::Reference< ucb::XSimpleFileAccess3 >& xSFI = getFileAccess(); - if( xSFI.is() ) + OUString aFullPath = getFullPath( aFileSpec ); + if( !xSFI->exists( aFullPath ) || xSFI->isFolder( aFullPath ) ) { - OUString aFullPath = getFullPath( aFileSpec ); - if( !xSFI->exists( aFullPath ) || xSFI->isFolder( aFullPath ) ) - { - StarBASIC::Error( ERRCODE_BASIC_FILE_NOT_FOUND ); - return; - } - try - { - xSFI->kill( aFullPath ); - } - catch(const Exception & ) - { - StarBASIC::Error( ERRCODE_IO_GENERAL ); - } + StarBASIC::Error( ERRCODE_BASIC_FILE_NOT_FOUND ); + return; + } + try + { + xSFI->kill( aFullPath ); + } + catch(const Exception & ) + { + StarBASIC::Error( ERRCODE_IO_GENERAL ); } - } - else - { - File::remove( getFullPath( aFileSpec ) ); } } else { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + File::remove( getFullPath( aFileSpec ) ); } } void SbRtl_MkDir(StarBASIC * pBasic, SbxArray & rPar, bool bWrite) { rPar.Get(0)->PutEmpty(); - if (rPar.Count() == 2) + if (rPar.Count() != 2) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + OUString aPath = rPar.Get(1)->GetOUString(); + if ( SbiRuntime::isVBAEnabled() ) { - OUString aPath = rPar.Get(1)->GetOUString(); - if ( SbiRuntime::isVBAEnabled() ) + // In vba if the full path is not specified then + // folder is created relative to the curdir + INetURLObject aURLObj( getFullPath( aPath ) ); + if ( aURLObj.GetProtocol() != INetProtocol::File ) { - // In vba if the full path is not specified then - // folder is created relative to the curdir - INetURLObject aURLObj( getFullPath( aPath ) ); - if ( aURLObj.GetProtocol() != INetProtocol::File ) - { - SbxArrayRef pPar = new SbxArray(); - SbxVariableRef pResult = new SbxVariable(); - SbxVariableRef pParam = new SbxVariable(); - pPar->Insert(pResult.get(), pPar->Count()); - pPar->Insert(pParam.get(), pPar->Count()); - SbRtl_CurDir( pBasic, *pPar, bWrite ); - - OUString sCurPathURL; - File::getFileURLFromSystemPath(pPar->Get(0)->GetOUString(), sCurPathURL); - - aURLObj.SetURL( sCurPathURL ); - aURLObj.Append( aPath ); - File::getSystemPathFromFileURL(aURLObj.GetMainURL( INetURLObject::DecodeMechanism::ToIUri ),aPath ) ; - } + SbxArrayRef pPar = new SbxArray(); + SbxVariableRef pResult = new SbxVariable(); + SbxVariableRef pParam = new SbxVariable(); + pPar->Insert(pResult.get(), pPar->Count()); + pPar->Insert(pParam.get(), pPar->Count()); + SbRtl_CurDir( pBasic, *pPar, bWrite ); + + OUString sCurPathURL; + File::getFileURLFromSystemPath(pPar->Get(0)->GetOUString(), sCurPathURL); + + aURLObj.SetURL( sCurPathURL ); + aURLObj.Append( aPath ); + File::getSystemPathFromFileURL(aURLObj.GetMainURL( INetURLObject::DecodeMechanism::ToIUri ),aPath ) ; } + } - if( hasUno() ) + if( hasUno() ) + { + const uno::Reference< ucb::XSimpleFileAccess3 >& xSFI = getFileAccess(); + if( xSFI.is() ) { - const uno::Reference< ucb::XSimpleFileAccess3 >& xSFI = getFileAccess(); - if( xSFI.is() ) + try { - try - { - xSFI->createFolder( getFullPath( aPath ) ); - } - catch(const Exception & ) - { - StarBASIC::Error( ERRCODE_IO_GENERAL ); - } + xSFI->createFolder( getFullPath( aPath ) ); + } + catch(const Exception & ) + { + StarBASIC::Error( ERRCODE_IO_GENERAL ); } - } - else - { - Directory::create( getFullPath( aPath ) ); } } else { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + Directory::create( getFullPath( aPath ) ); } } @@ -673,16 +630,14 @@ static void implRemoveDirRecursive( const OUString& aDirPath ) if( !bExists || !bFolder ) { - StarBASIC::Error( ERRCODE_BASIC_PATH_NOT_FOUND ); - return; + return StarBASIC::Error( ERRCODE_BASIC_PATH_NOT_FOUND ); } Directory aDir( aDirPath ); nRet = aDir.open(); if( nRet != FileBase::E_None ) { - StarBASIC::Error( ERRCODE_BASIC_PATH_NOT_FOUND ); - return; + return StarBASIC::Error( ERRCODE_BASIC_PATH_NOT_FOUND ); } aDir.close(); @@ -693,49 +648,43 @@ static void implRemoveDirRecursive( const OUString& aDirPath ) void SbRtl_RmDir(StarBASIC *, SbxArray & rPar, bool) { rPar.Get(0)->PutEmpty(); - if (rPar.Count() == 2) + if (rPar.Count() != 2) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + OUString aPath = rPar.Get(1)->GetOUString(); + if( hasUno() ) { - OUString aPath = rPar.Get(1)->GetOUString(); - if( hasUno() ) + const uno::Reference< ucb::XSimpleFileAccess3 >& xSFI = getFileAccess(); + if( xSFI.is() ) { - const uno::Reference< ucb::XSimpleFileAccess3 >& xSFI = getFileAccess(); - if( xSFI.is() ) + try { - try + if( !xSFI->isFolder( aPath ) ) { - if( !xSFI->isFolder( aPath ) ) - { - StarBASIC::Error( ERRCODE_BASIC_PATH_NOT_FOUND ); - return; - } - SbiInstance* pInst = GetSbData()->pInst; - bool bCompatibility = ( pInst && pInst->IsCompatibility() ); - if( bCompatibility ) - { - Sequence< OUString > aContent = xSFI->getFolderContents( aPath, true ); - if( aContent.hasElements() ) - { - StarBASIC::Error( ERRCODE_BASIC_ACCESS_ERROR ); - return; - } - } - - xSFI->kill( getFullPath( aPath ) ); + return StarBASIC::Error( ERRCODE_BASIC_PATH_NOT_FOUND ); } - catch(const Exception & ) + SbiInstance* pInst = GetSbData()->pInst; + bool bCompatibility = ( pInst && pInst->IsCompatibility() ); + if( bCompatibility ) { - StarBASIC::Error( ERRCODE_IO_GENERAL ); + Sequence< OUString > aContent = xSFI->getFolderContents( aPath, true ); + if( aContent.hasElements() ) + { + return StarBASIC::Error( ERRCODE_BASIC_ACCESS_ERROR ); + } } + + xSFI->kill( getFullPath( aPath ) ); + } + catch(const Exception & ) + { + StarBASIC::Error( ERRCODE_IO_GENERAL ); } - } - else - { - implRemoveDirRecursive( getFullPath( aPath ) ); } } else { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + implRemoveDirRecursive( getFullPath( aPath ) ); } } @@ -748,91 +697,79 @@ void SbRtl_SendKeys(StarBASIC *, SbxArray & rPar, bool) void SbRtl_Exp(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() < 2) - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - else - { - double aDouble = rPar.Get(1)->GetDouble(); - aDouble = exp( aDouble ); - checkArithmeticOverflow( aDouble ); - rPar.Get(0)->PutDouble(aDouble); - } + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + double aDouble = rPar.Get(1)->GetDouble(); + aDouble = exp( aDouble ); + checkArithmeticOverflow( aDouble ); + rPar.Get(0)->PutDouble(aDouble); } void SbRtl_FileLen(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() < 2) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); } - else + + SbxVariableRef pArg = rPar.Get(1); + OUString aStr( pArg->GetOUString() ); + sal_Int32 nLen = 0; + if( hasUno() ) { - SbxVariableRef pArg = rPar.Get(1); - OUString aStr( pArg->GetOUString() ); - sal_Int32 nLen = 0; - if( hasUno() ) + const uno::Reference< ucb::XSimpleFileAccess3 >& xSFI = getFileAccess(); + if( xSFI.is() ) { - const uno::Reference< ucb::XSimpleFileAccess3 >& xSFI = getFileAccess(); - if( xSFI.is() ) + try { - try - { - nLen = xSFI->getSize( getFullPath( aStr ) ); - } - catch(const Exception & ) - { - StarBASIC::Error( ERRCODE_IO_GENERAL ); - } + nLen = xSFI->getSize( getFullPath( aStr ) ); + } + catch(const Exception & ) + { + StarBASIC::Error( ERRCODE_IO_GENERAL ); } } - else - { - DirectoryItem aItem; - (void)DirectoryItem::get( getFullPath( aStr ), aItem ); - FileStatus aFileStatus( osl_FileStatus_Mask_FileSize ); - (void)aItem.getFileStatus( aFileStatus ); - nLen = static_cast<sal_Int32>(aFileStatus.getFileSize()); - } - rPar.Get(0)->PutLong(static_cast<tools::Long>(nLen)); } + else + { + DirectoryItem aItem; + (void)DirectoryItem::get( getFullPath( aStr ), aItem ); + FileStatus aFileStatus( osl_FileStatus_Mask_FileSize ); + (void)aItem.getFileStatus( aFileStatus ); + nLen = static_cast<sal_Int32>(aFileStatus.getFileSize()); + } + rPar.Get(0)->PutLong(nLen); } + void SbRtl_Hex(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() < 2) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } - else - { - SbxVariableRef pArg = rPar.Get(1); - // converting value to unsigned and limit to 2 or 4 byte representation - sal_uInt32 nVal = pArg->IsInteger() ? - static_cast<sal_uInt16>(pArg->GetInteger()) : - static_cast<sal_uInt32>(pArg->GetLong()); - OUString aStr(OUString::number( nVal, 16 )); - aStr = aStr.toAsciiUpperCase(); - rPar.Get(0)->PutString(aStr); + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); } + + SbxVariableRef pArg = rPar.Get(1); + // converting value to unsigned and limit to 2 or 4 byte representation + sal_uInt32 nVal = pArg->IsInteger() ? + static_cast<sal_uInt16>(pArg->GetInteger()) : + static_cast<sal_uInt32>(pArg->GetLong()); + rPar.Get(0)->PutString(OUString::number(nVal, 16).toAsciiUpperCase()); } void SbRtl_FuncCaller(StarBASIC *, SbxArray & rPar, bool) { - if ( SbiRuntime::isVBAEnabled() && GetSbData()->pInst && GetSbData()->pInst->pRun ) - { - if ( GetSbData()->pInst->pRun->GetExternalCaller() ) - *rPar.Get(0) = *GetSbData()->pInst->pRun->GetExternalCaller(); - else - { - SbxVariableRef pVar = new SbxVariable(SbxVARIANT); - *rPar.Get(0) = *pVar; - } - } + if (!SbiRuntime::isVBAEnabled() || GetSbData()->pInst == nullptr || GetSbData()->pInst->pRun == nullptr) + return StarBASIC::Error(ERRCODE_BASIC_NOT_IMPLEMENTED); + + if ( GetSbData()->pInst->pRun->GetExternalCaller() ) + *rPar.Get(0) = *GetSbData()->pInst->pRun->GetExternalCaller(); else { - StarBASIC::Error( ERRCODE_BASIC_NOT_IMPLEMENTED ); + SbxVariableRef pVar = new SbxVariable(SbxVARIANT); + *rPar.Get(0) = *pVar; } - } // InStr( [start],string,string,[compare] ) @@ -840,79 +777,77 @@ void SbRtl_InStr(StarBASIC *, SbxArray & rPar, bool) { const sal_uInt32 nArgCount = rPar.Count() - 1; if ( nArgCount < 2 ) - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - else - { - sal_Int32 nStartPos = 1; - sal_Int32 nFirstStringPos = 1; + return StarBASIC::Error(ERRCODE_BASIC_BAD_ARGUMENT); - if ( nArgCount >= 3 ) - { - nStartPos = rPar.Get(1)->GetLong(); - if( nStartPos <= 0 ) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - nStartPos = 1; - } - nFirstStringPos++; - } + sal_Int32 nStartPos = 1; + sal_Int32 nFirstStringPos = 1; - SbiInstance* pInst = GetSbData()->pInst; - bool bTextMode; - bool bCompatibility = ( pInst && pInst->IsCompatibility() ); - if( bCompatibility ) - { - SbiRuntime* pRT = pInst->pRun; - bTextMode = pRT && pRT->IsImageFlag( SbiImageFlags::COMPARETEXT ); - } - else - { - bTextMode = true; - } - if ( nArgCount == 4 ) + if ( nArgCount >= 3 ) + { + nStartPos = rPar.Get(1)->GetLong(); + if( nStartPos <= 0 ) { - bTextMode = rPar.Get(4)->GetInteger(); + StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + nStartPos = 1; } - sal_Int32 nPos; - const OUString& rToken = rPar.Get(nFirstStringPos + 1)->GetOUString(); + nFirstStringPos++; + } - // #97545 Always find empty string - if( rToken.isEmpty() ) + SbiInstance* pInst = GetSbData()->pInst; + bool bTextMode; + bool bCompatibility = ( pInst && pInst->IsCompatibility() ); + if( bCompatibility ) + { + SbiRuntime* pRT = pInst->pRun; + bTextMode = pRT && pRT->IsImageFlag( SbiImageFlags::COMPARETEXT ); + } + else + { + bTextMode = true; + } + if ( nArgCount == 4 ) + { + bTextMode = rPar.Get(4)->GetInteger(); + } + sal_Int32 nPos; + const OUString aToken = rPar.Get(nFirstStringPos + 1)->GetOUString(); + + // #97545 Always find empty string + if( aToken.isEmpty() ) + { + nPos = nStartPos; + } + else + { + const OUString aStr1 = rPar.Get(nFirstStringPos)->GetOUString(); + const sal_Int32 nrStr1Len = aStr1.getLength(); + if (nStartPos > nrStr1Len) { - nPos = nStartPos; + // Start position is greater than the string being searched + nPos = 0; } else { - const OUString& rStr1 = rPar.Get(nFirstStringPos)->GetOUString(); - const sal_Int32 nrStr1Len = rStr1.getLength(); - if (nStartPos > nrStr1Len) + if( !bTextMode ) { - // Start position is greater than the string being searched - nPos = 0; + nPos = aStr1.indexOf( aToken, nStartPos - 1 ) + 1; } else { - if( !bTextMode ) - { - nPos = rStr1.indexOf( rToken, nStartPos - 1 ) + 1; - } - else - { - // tdf#139840 - case-insensitive operation for non-ASCII characters - i18nutil::SearchOptions2 aSearchOptions; - aSearchOptions.searchString = rToken; - aSearchOptions.AlgorithmType2 = util::SearchAlgorithms2::ABSOLUTE; - aSearchOptions.transliterateFlags |= TransliterationFlags::IGNORE_CASE; - utl::TextSearch textSearch(aSearchOptions); - - sal_Int32 nStart = nStartPos - 1; - sal_Int32 nEnd = nrStr1Len; - nPos = textSearch.SearchForward(rStr1, &nStart, &nEnd) ? nStart + 1 : 0; - } + // tdf#139840 - case-insensitive operation for non-ASCII characters + i18nutil::SearchOptions2 aSearchOptions; + aSearchOptions.searchString = aToken; + aSearchOptions.AlgorithmType2 = util::SearchAlgorithms2::ABSOLUTE; + aSearchOptions.transliterateFlags |= TransliterationFlags::IGNORE_CASE; + utl::TextSearch textSearch(aSearchOptions); + + sal_Int32 nStart = nStartPos - 1; + sal_Int32 nEnd = nrStr1Len; + nPos = textSearch.SearchForward(aStr1, &nStart, &nEnd) ? nStart + 1 : 0; } } - rPar.Get(0)->PutLong(nPos); } + rPar.Get(0)->PutLong(nPos); } @@ -923,78 +858,76 @@ void SbRtl_InStrRev(StarBASIC *, SbxArray & rPar, bool) const sal_uInt32 nArgCount = rPar.Count() - 1; if ( nArgCount < 2 ) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); } - else - { - const OUString aStr1 = rPar.Get(1)->GetOUString(); - const OUString aToken = rPar.Get(2)->GetOUString(); - sal_Int32 nStartPos = -1; - if ( nArgCount >= 3 ) - { - nStartPos = rPar.Get(3)->GetLong(); - if( nStartPos <= 0 && nStartPos != -1 ) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - nStartPos = -1; - } - } + const OUString aStr1 = rPar.Get(1)->GetOUString(); + const OUString aToken = rPar.Get(2)->GetOUString(); - SbiInstance* pInst = GetSbData()->pInst; - bool bTextMode; - bool bCompatibility = ( pInst && pInst->IsCompatibility() ); - if( bCompatibility ) - { - SbiRuntime* pRT = pInst->pRun; - bTextMode = pRT && pRT->IsImageFlag( SbiImageFlags::COMPARETEXT ); - } - else - { - bTextMode = true; - } - if ( nArgCount == 4 ) + sal_Int32 nStartPos = -1; + if ( nArgCount >= 3 ) + { + nStartPos = rPar.Get(3)->GetLong(); + if( nStartPos <= 0 && nStartPos != -1 ) { - bTextMode = rPar.Get(4)->GetInteger(); + StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + nStartPos = -1; } - const sal_Int32 nStrLen = aStr1.getLength(); - if( nStartPos == -1 ) + } + + SbiInstance* pInst = GetSbData()->pInst; + bool bTextMode; + bool bCompatibility = ( pInst && pInst->IsCompatibility() ); + if( bCompatibility ) + { + SbiRuntime* pRT = pInst->pRun; + bTextMode = pRT && pRT->IsImageFlag( SbiImageFlags::COMPARETEXT ); + } + else + { + bTextMode = true; + } + if ( nArgCount == 4 ) + { + bTextMode = rPar.Get(4)->GetInteger(); + } + const sal_Int32 nStrLen = aStr1.getLength(); + if( nStartPos == -1 ) + { + nStartPos = nStrLen; + } + + sal_Int32 nPos = 0; + if( nStartPos <= nStrLen ) + { + sal_Int32 nTokenLen = aToken.getLength(); + if( !nTokenLen ) { - nStartPos = nStrLen; + // Always find empty string + nPos = nStartPos; } - - sal_Int32 nPos = 0; - if( nStartPos <= nStrLen ) + else if( nStrLen > 0 ) { - sal_Int32 nTokenLen = aToken.getLength(); - if( !nTokenLen ) + if( !bTextMode ) { - // Always find empty string - nPos = nStartPos; + nPos = aStr1.lastIndexOf( aToken, nStartPos ) + 1; } - else if( nStrLen > 0 ) + else { - if( !bTextMode ) - { - nPos = aStr1.lastIndexOf( aToken, nStartPos ) + 1; - } - else - { - // tdf#143332 - case-insensitive operation for non-ASCII characters - i18nutil::SearchOptions2 aSearchOptions; - aSearchOptions.searchString = aToken; - aSearchOptions.AlgorithmType2 = util::SearchAlgorithms2::ABSOLUTE; - aSearchOptions.transliterateFlags |= TransliterationFlags::IGNORE_CASE; - utl::TextSearch textSearch(aSearchOptions); - - sal_Int32 nStart = 0; - sal_Int32 nEnd = nStartPos; - nPos = textSearch.SearchBackward(aStr1, &nEnd, &nStart) ? nStart : 0; - } + // tdf#143332 - case-insensitive operation for non-ASCII characters + i18nutil::SearchOptions2 aSearchOptions; + aSearchOptions.searchString = aToken; + aSearchOptions.AlgorithmType2 = util::SearchAlgorithms2::ABSOLUTE; + aSearchOptions.transliterateFlags |= TransliterationFlags::IGNORE_CASE; + utl::TextSearch textSearch(aSearchOptions); + + sal_Int32 nStart = 0; + sal_Int32 nEnd = nStartPos; + nPos = textSearch.SearchBackward(aStr1, &nEnd, &nStart) ? nStart : 0; } } - rPar.Get(0)->PutLong(nPos); } + rPar.Get(0)->PutLong(nPos); } @@ -1008,110 +941,86 @@ void SbRtl_InStrRev(StarBASIC *, SbxArray & rPar, bool) void SbRtl_Int(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() < 2) - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - else - { - SbxVariableRef pArg = rPar.Get(1); - double aDouble= pArg->GetDouble(); - /* - floor( 2.8 ) = 2.0 - floor( -2.8 ) = -3.0 - */ - aDouble = floor( aDouble ); - rPar.Get(0)->PutDouble(aDouble); - } + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + SbxVariableRef pArg = rPar.Get(1); + double aDouble= pArg->GetDouble(); + /* + floor( 2.8 ) = 2.0 + floor( -2.8 ) = -3.0 + */ + aDouble = floor( aDouble ); + rPar.Get(0)->PutDouble(aDouble); } void SbRtl_Fix(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() < 2) - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + SbxVariableRef pArg = rPar.Get(1); + double aDouble = pArg->GetDouble(); + if ( aDouble >= 0.0 ) + aDouble = floor( aDouble ); else - { - SbxVariableRef pArg = rPar.Get(1); - double aDouble = pArg->GetDouble(); - if ( aDouble >= 0.0 ) - aDouble = floor( aDouble ); - else - aDouble = ceil( aDouble ); - rPar.Get(0)->PutDouble(aDouble); - } + aDouble = ceil( aDouble ); + rPar.Get(0)->PutDouble(aDouble); } void SbRtl_LCase(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() < 2) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } - else - { - const CharClass& rCharClass = GetCharClass(); - OUString aStr(rPar.Get(1)->GetOUString()); - aStr = rCharClass.lowercase(aStr); - rPar.Get(0)->PutString(aStr); - } + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + const CharClass& rCharClass = GetCharClass(); + OUString aStr(rPar.Get(1)->GetOUString()); + aStr = rCharClass.lowercase(aStr); + rPar.Get(0)->PutString(aStr); } void SbRtl_Left(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() < 3) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + OUString aStr(rPar.Get(1)->GetOUString()); + sal_Int32 nResultLen = rPar.Get(2)->GetLong(); + if( nResultLen < 0 ) { + nResultLen = 0; StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); } - else + else if(nResultLen > aStr.getLength()) { - OUString aStr(rPar.Get(1)->GetOUString()); - sal_Int32 nResultLen = rPar.Get(2)->GetLong(); - if( nResultLen < 0 ) - { - nResultLen = 0; - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } - else if(nResultLen > aStr.getLength()) - { - nResultLen = aStr.getLength(); - } - aStr = aStr.copy(0, nResultLen ); - rPar.Get(0)->PutString(aStr); + nResultLen = aStr.getLength(); } + aStr = aStr.copy(0, nResultLen ); + rPar.Get(0)->PutString(aStr); } void SbRtl_Log(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() < 2) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } - else - { - double aArg = rPar.Get(1)->GetDouble(); - if ( aArg > 0 ) - { - double d = log( aArg ); - checkArithmeticOverflow( d ); - rPar.Get(0)->PutDouble(d); - } - else - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } - } + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + double aArg = rPar.Get(1)->GetDouble(); + if ( aArg <= 0 ) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + double d = log( aArg ); + checkArithmeticOverflow( d ); + rPar.Get(0)->PutDouble(d); } void SbRtl_LTrim(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() < 2) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } - else - { - OUString aStr(comphelper::string::stripStart(rPar.Get(1)->GetOUString(), ' ')); - rPar.Get(0)->PutString(aStr); - } + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + OUString aStr(comphelper::string::stripStart(rPar.Get(1)->GetOUString(), ' ')); + rPar.Get(0)->PutString(aStr); } @@ -1122,137 +1031,119 @@ void SbRtl_Mid(StarBASIC *, SbxArray & rPar, bool bWrite) int nArgCount = rPar.Count() - 1; if ( nArgCount < 2 ) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + return StarBASIC::Error(ERRCODE_BASIC_BAD_ARGUMENT); } - else + // #23178: replicate the functionality of Mid$ as a command + // by adding a replacement-string as a fourth parameter. + // In contrast to the original the third parameter (nLength) + // can't be left out here. That's considered in bWrite already. + if( nArgCount == 4 ) { - // #23178: replicate the functionality of Mid$ as a command - // by adding a replacement-string as a fourth parameter. - // In contrast to the original the third parameter (nLength) - // can't be left out here. That's considered in bWrite already. - if( nArgCount == 4 ) - { - bWrite = true; - } - OUString aArgStr = rPar.Get(1)->GetOUString(); - sal_Int32 nStartPos = rPar.Get(2)->GetLong(); - if ( nStartPos < 1 ) + bWrite = true; + } + OUString aArgStr = rPar.Get(1)->GetOUString(); + sal_Int32 nStartPos = rPar.Get(2)->GetLong(); + if ( nStartPos < 1 ) + { + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + } + + nStartPos--; + sal_Int32 nLen = -1; + bool bWriteNoLenParam = false; + if ( nArgCount == 3 || bWrite ) + { + sal_Int32 n = rPar.Get(3)->GetLong(); + if( bWrite && n == -1 ) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + bWriteNoLenParam = true; } - else + nLen = n; + } + if ( bWrite ) + { + sal_Int32 nArgLen = aArgStr.getLength(); + if( nStartPos > nArgLen ) { - nStartPos--; - sal_Int32 nLen = -1; - bool bWriteNoLenParam = false; - if ( nArgCount == 3 || bWrite ) + SbiInstance* pInst = GetSbData()->pInst; + bool bCompatibility = ( pInst && pInst->IsCompatibility() ); + if( bCompatibility ) { - sal_Int32 n = rPar.Get(3)->GetLong(); - if( bWrite && n == -1 ) - { - bWriteNoLenParam = true; - } - nLen = n; + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); } - if ( bWrite ) - { - sal_Int32 nArgLen = aArgStr.getLength(); - if( nStartPos > nArgLen ) - { - SbiInstance* pInst = GetSbData()->pInst; - bool bCompatibility = ( pInst && pInst->IsCompatibility() ); - if( bCompatibility ) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; - } - nStartPos = nArgLen; - } - - OUString aReplaceStr = rPar.Get(4)->GetOUString(); - sal_Int32 nReplaceStrLen = aReplaceStr.getLength(); - sal_Int32 nReplaceLen; - if( bWriteNoLenParam ) - { - nReplaceLen = nArgLen - nStartPos; - } - else - { - nReplaceLen = nLen; - if( nReplaceLen < 0 || nReplaceLen > nArgLen - nStartPos ) - { - nReplaceLen = nArgLen - nStartPos; - } - } - - OUStringBuffer aResultStr(aArgStr); - sal_Int32 nErase = nReplaceLen; - aResultStr.remove( nStartPos, nErase ); - aResultStr.insert( - nStartPos, aReplaceStr.getStr(), std::min(nReplaceLen, nReplaceStrLen)); + nStartPos = nArgLen; + } - rPar.Get(1)->PutString(aResultStr.makeStringAndClear()); - } - else + OUString aReplaceStr = rPar.Get(4)->GetOUString(); + sal_Int32 nReplaceStrLen = aReplaceStr.getLength(); + sal_Int32 nReplaceLen; + if( bWriteNoLenParam ) + { + nReplaceLen = nArgLen - nStartPos; + } + else + { + nReplaceLen = nLen; + if( nReplaceLen < 0 || nReplaceLen > nArgLen - nStartPos ) { - OUString aResultStr; - if (nStartPos > aArgStr.getLength()) - { - // do nothing - } - else if(nArgCount == 2) - { - aResultStr = aArgStr.copy( nStartPos); - } - else - { - if (nLen < 0) - nLen = 0; - if(nStartPos + nLen > aArgStr.getLength()) - { - nLen = aArgStr.getLength() - nStartPos; - } - if (nLen > 0) - aResultStr = aArgStr.copy( nStartPos, nLen ); - } - rPar.Get(0)->PutString(aResultStr); + nReplaceLen = nArgLen - nStartPos; } } - } -} -void SbRtl_Oct(StarBASIC *, SbxArray & rPar, bool) -{ - if (rPar.Count() < 2) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + OUStringBuffer aResultStr(aArgStr); + sal_Int32 nErase = nReplaceLen; + aResultStr.remove( nStartPos, nErase ); + aResultStr.insert( + nStartPos, aReplaceStr.getStr(), std::min(nReplaceLen, nReplaceStrLen)); + + rPar.Get(1)->PutString(aResultStr.makeStringAndClear()); } else { - char aBuffer[16]; - SbxVariableRef pArg = rPar.Get(1); - if ( pArg->IsInteger() ) + OUString aResultStr; + if (nStartPos > aArgStr.getLength()) + { + // do nothing + } + else if(nArgCount == 2) { - snprintf( aBuffer, sizeof(aBuffer), "%o", pArg->GetInteger() ); + aResultStr = aArgStr.copy( nStartPos); } else { - snprintf( aBuffer, sizeof(aBuffer), "%lo", static_cast<long unsigned int>(pArg->GetLong()) ); + if (nLen < 0) + nLen = 0; + if(nStartPos + nLen > aArgStr.getLength()) + { + nLen = aArgStr.getLength() - nStartPos; + } + if (nLen > 0) + aResultStr = aArgStr.copy( nStartPos, nLen ); } - rPar.Get(0)->PutString(OUString::createFromAscii(aBuffer)); + rPar.Get(0)->PutString(aResultStr); } } +void SbRtl_Oct(StarBASIC *, SbxArray & rPar, bool) +{ + if (rPar.Count() < 2) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + SbxVariableRef pArg = rPar.Get(1); + // converting value to unsigned and limit to 2 or 4 byte representation + sal_uInt32 nVal = pArg->IsInteger() ? + static_cast<sal_uInt16>(pArg->GetInteger()) : + static_cast<sal_uInt32>(pArg->GetLong()); + rPar.Get(0)->PutString(OUString::number(nVal, 8)); +} + // Replace(expression, find, replace[, start[, count[, compare]]]) void SbRtl_Replace(StarBASIC *, SbxArray & rPar, bool) { const sal_uInt32 nArgCount = rPar.Count() - 1; if ( nArgCount < 3 || nArgCount > 6 ) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; - } + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); sal_Int32 lStartPos = 1; if (nArgCount >= 4) @@ -1263,10 +1154,10 @@ void SbRtl_Replace(StarBASIC *, SbxArray & rPar, bool) } if (lStartPos < 1) { - StarBASIC::Error(ERRCODE_BASIC_BAD_ARGUMENT); - return; + return StarBASIC::Error(ERRCODE_BASIC_BAD_ARGUMENT); } } + --lStartPos; // Make it 0-based sal_Int32 lCount = -1; if (nArgCount >= 5) @@ -1277,8 +1168,7 @@ void SbRtl_Replace(StarBASIC *, SbxArray & rPar, bool) } if (lCount < -1) { - StarBASIC::Error(ERRCODE_BASIC_BAD_ARGUMENT); - return; + return StarBASIC::Error(ERRCODE_BASIC_BAD_ARGUMENT); } } @@ -1302,66 +1192,74 @@ void SbRtl_Replace(StarBASIC *, SbxArray & rPar, bool) } const OUString aExpStr = rPar.Get(1)->GetOUString(); - const OUString aFindStr = rPar.Get(2)->GetOUString(); + OUString aFindStr = rPar.Get(2)->GetOUString(); const OUString aReplaceStr = rPar.Get(3)->GetOUString(); - const sal_Int32 nExpStrLen = aExpStr.getLength(); - const sal_Int32 nFindStrLen = aFindStr.getLength(); - // tdf#142487 - use utl::TextSearch in order to implement the replace algorithm - i18nutil::SearchOptions2 aSearchOptions; - aSearchOptions.searchString = aFindStr; - aSearchOptions.AlgorithmType2 = util::SearchAlgorithms2::ABSOLUTE; + OUString aSrcStr(aExpStr); + sal_Int32 nPrevPos = std::min(lStartPos, aSrcStr.getLength()); + css::uno::Sequence<sal_Int32> aOffset; if (bCaseInsensitive) - aSearchOptions.transliterateFlags |= TransliterationFlags::IGNORE_CASE; - utl::TextSearch textSearch(aSearchOptions); + { + // tdf#132389: case-insensitive operation for non-ASCII characters + // tdf#142487: use css::i18n::Transliteration to correctly handle ß -> ss expansion + // tdf#132388: We can't use utl::TextSearch (css::i18n::XTextSearch), because each call to + // css::i18n::XTextSearch::SearchForward transliterates input string, making + // performance of repeated calls unacceptable + auto xTrans = css::i18n::Transliteration::create(comphelper::getProcessComponentContext()); + xTrans->loadModule(css::i18n::TransliterationModules_IGNORE_CASE, {}); + aFindStr = xTrans->transliterate(aFindStr, 0, aFindStr.getLength(), aOffset); + aSrcStr = xTrans->transliterate(aSrcStr, nPrevPos, aSrcStr.getLength() - nPrevPos, aOffset); + nPrevPos = std::distance(aOffset.begin(), + std::lower_bound(aOffset.begin(), aOffset.end(), nPrevPos)); + } + + auto getExpStrPos = [aOffset, nExpLen = aExpStr.getLength()](sal_Int32 nSrcStrPos) -> sal_Int32 + { + assert(!aOffset.hasElements() || aOffset.getLength() >= nSrcStrPos); + if (!aOffset.hasElements()) + return nSrcStrPos; + return aOffset.getLength() > nSrcStrPos ? aOffset[nSrcStrPos] : nExpLen; + }; // Note: the result starts from lStartPos, removing everything to the left. See i#94895. - sal_Int32 nPrevPos = std::min(lStartPos - 1, nExpStrLen); - OUStringBuffer sResult(nExpStrLen - nPrevPos); + OUStringBuffer sResult(aSrcStr.getLength() - nPrevPos); sal_Int32 nCounts = 0; while (lCount == -1 || lCount > nCounts) { - sal_Int32 nStartPos = nPrevPos; - sal_Int32 aEndPos = aExpStr.getLength(); - if (textSearch.SearchForward(aExpStr, &nStartPos, &aEndPos)) - { - sResult.append(aExpStr.getStr() + nPrevPos, nStartPos - nPrevPos); - sResult.append(aReplaceStr); - nPrevPos = nStartPos + nFindStrLen; - nCounts++; - } - else - { + sal_Int32 nPos = aSrcStr.indexOf(aFindStr, nPrevPos); + if (nPos < 0) break; - } + + lStartPos = getExpStrPos(nPrevPos); + sResult.append(aExpStr.getStr() + lStartPos, getExpStrPos(nPos) - lStartPos); + sResult.append(aReplaceStr); + nPrevPos = nPos + aFindStr.getLength(); + nCounts++; } - sResult.append(aExpStr.getStr() + nPrevPos, nExpStrLen - nPrevPos); + lStartPos = getExpStrPos(nPrevPos); + sResult.append(aExpStr.getStr() + lStartPos, aExpStr.getLength() - lStartPos); rPar.Get(0)->PutString(sResult.makeStringAndClear()); } void SbRtl_Right(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() < 3) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + const OUString aStr = rPar.Get(1)->GetOUString(); + int nResultLen = rPar.Get(2)->GetLong(); + if( nResultLen < 0 ) { + nResultLen = 0; StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); } - else + int nStrLen = aStr.getLength(); + if ( nResultLen > nStrLen ) { - const OUString& rStr = rPar.Get(1)->GetOUString(); - int nResultLen = rPar.Get(2)->GetLong(); - if( nResultLen < 0 ) - { - nResultLen = 0; - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } - int nStrLen = rStr.getLength(); - if ( nResultLen > nStrLen ) - { - nResultLen = nStrLen; - } - OUString aResultStr = rStr.copy( nStrLen - nResultLen ); - rPar.Get(0)->PutString(aResultStr); + nResultLen = nStrLen; } + OUString aResultStr = aStr.copy( nStrLen - nResultLen ); + rPar.Get(0)->PutString(aResultStr); } void SbRtl_RTL(StarBASIC * pBasic, SbxArray & rPar, bool) @@ -1372,145 +1270,115 @@ void SbRtl_RTL(StarBASIC * pBasic, SbxArray & rPar, bool) void SbRtl_RTrim(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() < 2) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } - else - { - OUString aStr(comphelper::string::stripEnd(rPar.Get(1)->GetOUString(), ' ')); - rPar.Get(0)->PutString(aStr); - } + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + OUString aStr(comphelper::string::stripEnd(rPar.Get(1)->GetOUString(), ' ')); + rPar.Get(0)->PutString(aStr); } void SbRtl_Sgn(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() < 2) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + double aDouble = rPar.Get(1)->GetDouble(); + sal_Int16 nResult = 0; + if ( aDouble > 0 ) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + nResult = 1; } - else + else if ( aDouble < 0 ) { - double aDouble = rPar.Get(1)->GetDouble(); - sal_Int16 nResult = 0; - if ( aDouble > 0 ) - { - nResult = 1; - } - else if ( aDouble < 0 ) - { - nResult = -1; - } - rPar.Get(0)->PutInteger(nResult); + nResult = -1; } + rPar.Get(0)->PutInteger(nResult); } void SbRtl_Space(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() < 2) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } - else - { - OUStringBuffer aBuf; - string::padToLength(aBuf, rPar.Get(1)->GetLong(), ' '); - rPar.Get(0)->PutString(aBuf.makeStringAndClear()); + return StarBASIC::Error(ERRCODE_BASIC_BAD_ARGUMENT); } -} -void SbRtl_Spc(StarBASIC *, SbxArray & rPar, bool) -{ - if (rPar.Count() < 2) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } - else - { - OUStringBuffer aBuf; - string::padToLength(aBuf, rPar.Get(1)->GetLong(), ' '); - rPar.Get(0)->PutString(aBuf.makeStringAndClear()); - } + const sal_Int32 nCount = rPar.Get(1)->GetLong(); + OUStringBuffer aBuf(nCount); + string::padToLength(aBuf, nCount, ' '); + rPar.Get(0)->PutString(aBuf.makeStringAndClear()); } void SbRtl_Sqr(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() < 2) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + return StarBASIC::Error(ERRCODE_BASIC_BAD_ARGUMENT); } - else + + double aDouble = rPar.Get(1)->GetDouble(); + if ( aDouble < 0 ) { - double aDouble = rPar.Get(1)->GetDouble(); - if ( aDouble >= 0 ) - { - rPar.Get(0)->PutDouble(sqrt(aDouble)); - } - else - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); } + rPar.Get(0)->PutDouble(sqrt(aDouble)); } void SbRtl_Str(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() < 2) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + return StarBASIC::Error(ERRCODE_BASIC_BAD_ARGUMENT); } - else + + OUString aStr; + OUString aStrNew(u""_ustr); + SbxVariableRef pArg = rPar.Get(1); + pArg->Format( aStr ); + + // Numbers start with a space + if (pArg->GetType() != SbxBOOL && pArg->IsNumericRTL()) { - OUString aStr; - OUString aStrNew(""); - SbxVariableRef pArg = rPar.Get(1); - pArg->Format( aStr ); + // replace commas by points so that it's symmetric to Val! + aStr = aStr.replaceFirst( ",", "." ); - // Numbers start with a space - if( pArg->IsNumericRTL() ) + SbiInstance* pInst = GetSbData()->pInst; + bool bCompatibility = ( pInst && pInst->IsCompatibility() ); + if( bCompatibility ) { - // replace commas by points so that it's symmetric to Val! - aStr = aStr.replaceFirst( ",", "." ); - - SbiInstance* pInst = GetSbData()->pInst; - bool bCompatibility = ( pInst && pInst->IsCompatibility() ); - if( bCompatibility ) - { - sal_Int32 nLen = aStr.getLength(); + sal_Int32 nLen = aStr.getLength(); - const sal_Unicode* pBuf = aStr.getStr(); + const sal_Unicode* pBuf = aStr.getStr(); - bool bNeg = ( pBuf[0] == '-' ); - sal_Int32 iZeroSearch = 0; - if( bNeg ) - { - aStrNew += "-"; - iZeroSearch++; - } - else - { - if( pBuf[0] != ' ' ) - { - aStrNew += " "; - } - } - sal_Int32 iNext = iZeroSearch + 1; - if( pBuf[iZeroSearch] == '0' && nLen > iNext && pBuf[iNext] == '.' ) + bool bNeg = ( pBuf[0] == '-' ); + sal_Int32 iZeroSearch = 0; + if( bNeg ) + { + aStrNew += "-"; + iZeroSearch++; + } + else + { + if( pBuf[0] != ' ' ) { - iZeroSearch += 1; + aStrNew += " "; } - aStrNew += aStr.subView(iZeroSearch); } - else + sal_Int32 iNext = iZeroSearch + 1; + if( pBuf[iZeroSearch] == '0' && nLen > iNext && pBuf[iNext] == '.' ) { - aStrNew = " " + aStr; + iZeroSearch += 1; } + aStrNew += aStr.subView(iZeroSearch); } else { - aStrNew = aStr; + aStrNew = " " + aStr; } - rPar.Get(0)->PutString(aStrNew); } + else + { + aStrNew = aStr; + } + rPar.Get(0)->PutString(aStrNew); } void SbRtl_StrComp(StarBASIC *, SbxArray & rPar, bool) @@ -1521,8 +1389,8 @@ void SbRtl_StrComp(StarBASIC *, SbxArray & rPar, bool) rPar.Get(0)->PutEmpty(); return; } - const OUString& rStr1 = rPar.Get(1)->GetOUString(); - const OUString& rStr2 = rPar.Get(2)->GetOUString(); + const OUString aStr1 = rPar.Get(1)->GetOUString(); + const OUString aStr2 = rPar.Get(2)->GetOUString(); SbiInstance* pInst = GetSbData()->pInst; bool bTextCompare; @@ -1549,7 +1417,7 @@ void SbRtl_StrComp(StarBASIC *, SbxArray & rPar, bool) ::utl::TransliterationWrapper* pTransliterationWrapper = GetSbData()->pTransliterationWrapper.get(); if( !pTransliterationWrapper ) { - uno::Reference< uno::XComponentContext > xContext = getProcessComponentContext(); + const uno::Reference< uno::XComponentContext >& xContext = getProcessComponentContext(); GetSbData()->pTransliterationWrapper.reset( new ::utl::TransliterationWrapper( xContext, TransliterationFlags::IGNORE_CASE | @@ -1560,12 +1428,12 @@ void SbRtl_StrComp(StarBASIC *, SbxArray & rPar, bool) LanguageType eLangType = Application::GetSettings().GetLanguageTag().getLanguageType(); pTransliterationWrapper->loadModuleIfNeeded( eLangType ); - nRetValue = pTransliterationWrapper->compareString( rStr1, rStr2 ); + nRetValue = pTransliterationWrapper->compareString( aStr1, aStr2 ); } else { sal_Int32 aResult; - aResult = rStr1.compareTo( rStr2 ); + aResult = aStr1.compareTo( aStr2 ); if ( aResult < 0 ) { nRetValue = -1; @@ -1582,69 +1450,64 @@ void SbRtl_String(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() < 2) { + return StarBASIC::Error(ERRCODE_BASIC_BAD_ARGUMENT); + } + + sal_Unicode aFiller; + sal_Int32 lCount = rPar.Get(1)->GetLong(); + if( lCount < 0 || lCount > 0xffff ) + { StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); } + if (rPar.Get(2)->GetType() == SbxINTEGER) + { + aFiller = static_cast<sal_Unicode>(rPar.Get(2)->GetInteger()); + } else { - sal_Unicode aFiller; - sal_Int32 lCount = rPar.Get(1)->GetLong(); - if( lCount < 0 || lCount > 0xffff ) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } - if (rPar.Get(2)->GetType() == SbxINTEGER) - { - aFiller = static_cast<sal_Unicode>(rPar.Get(2)->GetInteger()); - } - else - { - const OUString& rStr = rPar.Get(2)->GetOUString(); - aFiller = rStr[0]; - } - OUStringBuffer aBuf(lCount); - string::padToLength(aBuf, lCount, aFiller); - rPar.Get(0)->PutString(aBuf.makeStringAndClear()); + const OUString aStr = rPar.Get(2)->GetOUString(); + aFiller = aStr[0]; } + OUStringBuffer aBuf(lCount); + string::padToLength(aBuf, lCount, aFiller); + rPar.Get(0)->PutString(aBuf.makeStringAndClear()); } void SbRtl_Tab(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() < 2) - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - else { - OUStringBuffer aStr; - comphelper::string::padToLength(aStr, rPar.Get(1)->GetLong(), '\t'); - rPar.Get(0)->PutString(aStr.makeStringAndClear()); + return StarBASIC::Error(ERRCODE_BASIC_BAD_ARGUMENT); } + + const sal_Int32 nCount = std::max(rPar.Get(1)->GetLong(), sal_Int32(0)); + OUStringBuffer aStr(nCount); + comphelper::string::padToLength(aStr, nCount, '\t'); + rPar.Get(0)->PutString(aStr.makeStringAndClear()); } void SbRtl_Tan(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() < 2) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } - else - { - SbxVariableRef pArg = rPar.Get(1); - rPar.Get(0)->PutDouble(tan(pArg->GetDouble())); + return StarBASIC::Error(ERRCODE_BASIC_BAD_ARGUMENT); } + + SbxVariableRef pArg = rPar.Get(1); + rPar.Get(0)->PutDouble(tan(pArg->GetDouble())); } void SbRtl_UCase(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() < 2) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } - else - { - const CharClass& rCharClass = GetCharClass(); - OUString aStr(rPar.Get(1)->GetOUString()); - aStr = rCharClass.uppercase( aStr ); - rPar.Get(0)->PutString(aStr); + return StarBASIC::Error(ERRCODE_BASIC_BAD_ARGUMENT); } + + const CharClass& rCharClass = GetCharClass(); + OUString aStr(rPar.Get(1)->GetOUString()); + aStr = rCharClass.uppercase( aStr ); + rPar.Get(0)->PutString(aStr); } @@ -1652,64 +1515,52 @@ void SbRtl_Val(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() < 2) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + return StarBASIC::Error(ERRCODE_BASIC_BAD_ARGUMENT); } - else - { - double nResult = 0.0; - char* pEndPtr; + double nResult = 0.0; - OUString aStr(rPar.Get(1)->GetOUString()); + OUString aStr(rPar.Get(1)->GetOUString()); - FilterWhiteSpace( aStr ); - if ( aStr.getLength() > 1 && aStr[0] == '&' ) + FilterWhiteSpace( aStr ); + if ( aStr.getLength() > 1 && aStr[0] == '&' ) + { + sal_Unicode aChar = aStr[1]; + if ( aChar == 'h' || aChar == 'H' ) { - int nRadix = 10; - char aChar = static_cast<char>(aStr[1]); - if ( aChar == 'h' || aChar == 'H' ) - { - nRadix = 16; - } - else if ( aChar == 'o' || aChar == 'O' ) - { - nRadix = 8; - } - if ( nRadix != 10 ) - { - OString aByteStr(OUStringToOString(aStr, osl_getThreadTextEncoding())); - sal_Int16 nlResult = static_cast<sal_Int16>(strtol( aByteStr.getStr()+2, &pEndPtr, nRadix)); - nResult = static_cast<double>(nlResult); - } + nResult = static_cast<sal_Int16>(o3tl::toInt64(aStr.subView(2), 16)); } - else + else if ( aChar == 'o' || aChar == 'O' ) { - rtl_math_ConversionStatus eStatus = rtl_math_ConversionStatus_Ok; - sal_Int32 nParseEnd = 0; - nResult = ::rtl::math::stringToDouble( aStr, '.', ',', &eStatus, &nParseEnd ); - if ( eStatus != rtl_math_ConversionStatus_Ok ) - StarBASIC::Error( ERRCODE_BASIC_MATH_OVERFLOW ); - /* TODO: we should check whether all characters were parsed here, - * but earlier code silently ignored trailing nonsense such as "1x" - * resulting in 1 with the side effect that any alpha-only-string - * like "x" resulted in 0. Not changing that now (2013-03-22) as - * user macros may rely on it. */ + nResult = static_cast<sal_Int16>(o3tl::toInt64(aStr.subView(2), 8)); + } + } + else + { + rtl_math_ConversionStatus eStatus = rtl_math_ConversionStatus_Ok; + sal_Int32 nParseEnd = 0; + nResult = ::rtl::math::stringToDouble( aStr, '.', ',', &eStatus, &nParseEnd ); + if ( eStatus != rtl_math_ConversionStatus_Ok ) + StarBASIC::Error( ERRCODE_BASIC_MATH_OVERFLOW ); + /* TODO: we should check whether all characters were parsed here, + * but earlier code silently ignored trailing nonsense such as "1x" + * resulting in 1 with the side effect that any alpha-only-string + * like "x" resulted in 0. Not changing that now (2013-03-22) as + * user macros may rely on it. */ #if 0 - else if ( nParseEnd != aStr.getLength() ) - StarBASIC::Error( ERRCODE_BASIC_CONVERSION ); + else if ( nParseEnd != aStr.getLength() ) + StarBASIC::Error( ERRCODE_BASIC_CONVERSION ); #endif - } - - rPar.Get(0)->PutDouble(nResult); } + + rPar.Get(0)->PutDouble(nResult); } // Helper functions for date conversion sal_Int16 implGetDateDay( double aDate ) { - aDate -= 2.0; // standardize: 1.1.1900 => 0.0 aDate = floor( aDate ); - Date aRefDate( 1, 1, 1900 ); + Date aRefDate(1899'12'30); aRefDate.AddDays( aDate ); sal_Int16 nRet = static_cast<sal_Int16>( aRefDate.GetDay() ); @@ -1718,9 +1569,8 @@ sal_Int16 implGetDateDay( double aDate ) sal_Int16 implGetDateMonth( double aDate ) { - Date aRefDate( 1,1,1900 ); + Date aRefDate(1899'12'30); sal_Int32 nDays = static_cast<sal_Int32>(aDate); - nDays -= 2; // standardize: 1.1.1900 => 0.0 aRefDate.AddDays( nDays ); sal_Int16 nRet = static_cast<sal_Int16>( aRefDate.GetMonth() ); return nRet; @@ -1752,8 +1602,7 @@ void SbRtl_CDateToUnoDate(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() != 2) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); } unoToSbxValue(rPar.Get(0), Any(SbxDateToUNODate(rPar.Get(1)))); @@ -1764,8 +1613,7 @@ void SbRtl_CDateFromUnoDate(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() != 2 || rPar.Get(1)->GetType() != SbxOBJECT) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); } Any aAny(sbxToUnoValue(rPar.Get(1), cppu::UnoType<css::util::Date>::get())); @@ -1784,14 +1632,15 @@ css::util::Time SbxDateToUNOTime( const SbxValue* const pVal ) aUnoTime.Hours = implGetHour ( aDate ); aUnoTime.Minutes = implGetMinute ( aDate ); aUnoTime.Seconds = implGetSecond ( aDate ); - aUnoTime.NanoSeconds = 0; + aUnoTime.NanoSeconds = implGetNanoSecond( aDate ); return aUnoTime; } void SbxDateFromUNOTime( SbxValue *pVal, const css::util::Time& aUnoTime) { - pVal->PutDate( implTimeSerial(aUnoTime.Hours, aUnoTime.Minutes, aUnoTime.Seconds) ); + pVal->PutDate(implTimeSerial(aUnoTime.Hours, aUnoTime.Minutes, aUnoTime.Seconds, + nanoSecToMilliSec(aUnoTime.NanoSeconds))); } // Function to convert date to UNO time (com.sun.star.util.Time) @@ -1799,8 +1648,7 @@ void SbRtl_CDateToUnoTime(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() != 2) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); } unoToSbxValue(rPar.Get(0), Any(SbxDateToUNOTime(rPar.Get(1)))); @@ -1811,8 +1659,7 @@ void SbRtl_CDateFromUnoTime(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() != 2 || rPar.Get(1)->GetType() != SbxOBJECT) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); } Any aAny(sbxToUnoValue(rPar.Get(1), cppu::UnoType<css::util::Time>::get())); @@ -1834,7 +1681,7 @@ css::util::DateTime SbxDateToUNODateTime( const SbxValue* const pVal ) aUnoDT.Hours = implGetHour ( aDate ); aUnoDT.Minutes = implGetMinute ( aDate ); aUnoDT.Seconds = implGetSecond ( aDate ); - aUnoDT.NanoSeconds = 0; + aUnoDT.NanoSeconds = implGetNanoSecond( aDate ); return aUnoDT; } @@ -1842,9 +1689,8 @@ css::util::DateTime SbxDateToUNODateTime( const SbxValue* const pVal ) void SbxDateFromUNODateTime( SbxValue *pVal, const css::util::DateTime& aUnoDT) { double dDate(0.0); - if( implDateTimeSerial( aUnoDT.Year, aUnoDT.Month, aUnoDT.Day, - aUnoDT.Hours, aUnoDT.Minutes, aUnoDT.Seconds, - dDate ) ) + if (implDateTimeSerial(aUnoDT.Year, aUnoDT.Month, aUnoDT.Day, aUnoDT.Hours, aUnoDT.Minutes, + aUnoDT.Seconds, nanoSecToMilliSec(aUnoDT.NanoSeconds), dDate)) { pVal->PutDate( dDate ); } @@ -1855,8 +1701,7 @@ void SbRtl_CDateToUnoDateTime(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() != 2) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); } unoToSbxValue(rPar.Get(0), Any(SbxDateToUNODateTime(rPar.Get(1)))); @@ -1867,8 +1712,7 @@ void SbRtl_CDateFromUnoDateTime(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() != 2 || rPar.Get(1)->GetType() != SbxOBJECT) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); } Any aAny(sbxToUnoValue(rPar.Get(1), cppu::UnoType<css::util::DateTime>::get())); @@ -1882,24 +1726,19 @@ void SbRtl_CDateFromUnoDateTime(StarBASIC *, SbxArray & rPar, bool) // Function to convert date to ISO 8601 date format YYYYMMDD void SbRtl_CDateToIso(StarBASIC *, SbxArray & rPar, bool) { - if (rPar.Count() == 2) - { - double aDate = rPar.Get(1)->GetDate(); + if (rPar.Count() != 2) + return StarBASIC::Error(ERRCODE_BASIC_BAD_ARGUMENT); - // Date may actually even be -YYYYYMMDD - char Buffer[11]; - sal_Int16 nYear = implGetDateYear( aDate ); - snprintf( Buffer, sizeof( Buffer ), (nYear < 0 ? "%05d%02d%02d" : "%04d%02d%02d"), - static_cast<int>(nYear), - static_cast<int>(implGetDateMonth( aDate )), - static_cast<int>(implGetDateDay( aDate )) ); - OUString aRetStr = OUString::createFromAscii( Buffer ); - rPar.Get(0)->PutString(aRetStr); - } - else - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } + double aDate = rPar.Get(1)->GetDate(); + + // Date may actually even be -YYYYYMMDD + char Buffer[11]; + sal_Int16 nYear = implGetDateYear(aDate); + snprintf(Buffer, sizeof(Buffer), (nYear < 0 ? "%05d%02d%02d" : "%04d%02d%02d"), + static_cast<int>(nYear), static_cast<int>(implGetDateMonth(aDate)), + static_cast<int>(implGetDateDay(aDate))); + OUString aRetStr = OUString::createFromAscii(Buffer); + rPar.Get(0)->PutString(aRetStr); } // Function to convert date from ISO 8601 date format YYYYMMDD or YYYY-MM-DD @@ -1937,7 +1776,7 @@ void SbRtl_CDateFromIso(StarBASIC *, SbxArray & rPar, bool) break; bool bUseTwoDigitYear = false; - OUString aYearStr, aMonthStr, aDayStr; + std::u16string_view aYearStr, aMonthStr, aDayStr; if (nLen == 6 || nLen == 8 || nLen == 9) { // ((Y)YY)YYMMDD @@ -1947,9 +1786,9 @@ void SbRtl_CDateFromIso(StarBASIC *, SbxArray & rPar, bool) const sal_Int32 nMonthPos = (nLen == 8 ? 4 : (nLen == 6 ? 2 : 5)); if (nMonthPos == 2) bUseTwoDigitYear = true; - aYearStr = aStr.copy( 0, nMonthPos ); - aMonthStr = aStr.copy( nMonthPos, 2 ); - aDayStr = aStr.copy( nMonthPos + 2, 2 ); + aYearStr = aStr.subView( 0, nMonthPos ); + aMonthStr = aStr.subView( nMonthPos, 2 ); + aDayStr = aStr.subView( nMonthPos + 2, 2 ); } else { @@ -1960,9 +1799,9 @@ void SbRtl_CDateFromIso(StarBASIC *, SbxArray & rPar, bool) if (aStr.indexOf('-', nMonthSep + 1) != nMonthSep + 3) break; - aYearStr = aStr.copy( 0, nMonthSep ); - aMonthStr = aStr.copy( nMonthSep + 1, 2 ); - aDayStr = aStr.copy( nMonthSep + 4, 2 ); + aYearStr = aStr.subView( 0, nMonthSep ); + aMonthStr = aStr.subView( nMonthSep + 1, 2 ); + aDayStr = aStr.subView( nMonthSep + 4, 2 ); if ( !comphelper::string::isdigitAsciiString(aYearStr) || !comphelper::string::isdigitAsciiString(aMonthStr) || !comphelper::string::isdigitAsciiString(aDayStr)) @@ -1970,8 +1809,8 @@ void SbRtl_CDateFromIso(StarBASIC *, SbxArray & rPar, bool) } double dDate; - if (!implDateSerial( static_cast<sal_Int16>(nSign * aYearStr.toInt32()), - static_cast<sal_Int16>(aMonthStr.toInt32()), static_cast<sal_Int16>(aDayStr.toInt32()), + if (!implDateSerial( static_cast<sal_Int16>(nSign * o3tl::toInt32(aYearStr)), + static_cast<sal_Int16>(o3tl::toInt32(aMonthStr)), static_cast<sal_Int16>(o3tl::toInt32(aDayStr)), bUseTwoDigitYear, SbDateCorrection::None, dDate )) break; @@ -1993,8 +1832,7 @@ void SbRtl_DateSerial(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() < 4) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); } sal_Int16 nYear = rPar.Get(1)->GetInteger(); sal_Int16 nMonth = rPar.Get(2)->GetInteger(); @@ -2011,8 +1849,7 @@ void SbRtl_TimeSerial(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() < 4) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); } sal_Int16 nHour = rPar.Get(1)->GetInteger(); if ( nHour == 24 ) @@ -2025,11 +1862,10 @@ void SbRtl_TimeSerial(StarBASIC *, SbxArray & rPar, bool) (nMinute < 0 || nMinute > 59 ) || (nSecond < 0 || nSecond > 59 )) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); } - rPar.Get(0)->PutDate(implTimeSerial(nHour, nMinute, nSecond)); // JSM + rPar.Get(0)->PutDate(implTimeSerial(nHour, nMinute, nSecond, 0)); // JSM } void SbRtl_DateValue(StarBASIC *, SbxArray & rPar, bool) @@ -2133,127 +1969,101 @@ void SbRtl_TimeValue(StarBASIC *, SbxArray & rPar, bool) void SbRtl_Day(StarBASIC *, SbxArray & rPar, bool) { - if (rPar.Count() < 2) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } - else - { - SbxVariableRef pArg = rPar.Get(1); - double aDate = pArg->GetDate(); + if (rPar.Count() != 2) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + SbxVariableRef pArg = rPar.Get(1); + double aDate = pArg->GetDate(); - sal_Int16 nDay = implGetDateDay( aDate ); - rPar.Get(0)->PutInteger(nDay); - } + sal_Int16 nDay = implGetDateDay( aDate ); + rPar.Get(0)->PutInteger(nDay); } void SbRtl_Year(StarBASIC *, SbxArray & rPar, bool) { - if (rPar.Count() < 2) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } - else - { - sal_Int16 nYear = implGetDateYear(rPar.Get(1)->GetDate()); - rPar.Get(0)->PutInteger(nYear); - } + if (rPar.Count() != 2) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + sal_Int16 nYear = implGetDateYear(rPar.Get(1)->GetDate()); + rPar.Get(0)->PutInteger(nYear); } sal_Int16 implGetHour( double dDate ) { - double nFrac = dDate - floor( dDate ); - nFrac *= 86400.0; - sal_Int32 nSeconds = static_cast<sal_Int32>(nFrac + 0.5); - sal_Int16 nHour = static_cast<sal_Int16>(nSeconds / 3600); - return nHour; + double nFrac = (dDate - floor(dDate)) * ::tools::Time::milliSecPerDay; + sal_uInt64 nMilliSeconds = static_cast<sal_uInt64>(nFrac + 0.5); + return static_cast<sal_Int16>((nMilliSeconds / ::tools::Time::milliSecPerHour) + % ::tools::Time::hourPerDay); } void SbRtl_Hour(StarBASIC *, SbxArray & rPar, bool) { - if (rPar.Count() < 2) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } - else - { - double nArg = rPar.Get(1)->GetDate(); - sal_Int16 nHour = implGetHour( nArg ); - rPar.Get(0)->PutInteger(nHour); - } + if (rPar.Count() != 2) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + double nArg = rPar.Get(1)->GetDate(); + sal_Int16 nHour = implGetHour( nArg ); + rPar.Get(0)->PutInteger(nHour); } void SbRtl_Minute(StarBASIC *, SbxArray & rPar, bool) { - if (rPar.Count() < 2) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } - else - { - double nArg = rPar.Get(1)->GetDate(); - sal_Int16 nMin = implGetMinute( nArg ); - rPar.Get(0)->PutInteger(nMin); - } + if (rPar.Count() != 2) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + double nArg = rPar.Get(1)->GetDate(); + sal_Int16 nMin = implGetMinute( nArg ); + rPar.Get(0)->PutInteger(nMin); } void SbRtl_Month(StarBASIC *, SbxArray & rPar, bool) { - if (rPar.Count() < 2) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } - else - { - sal_Int16 nMonth = implGetDateMonth(rPar.Get(1)->GetDate()); - rPar.Get(0)->PutInteger(nMonth); - } + if (rPar.Count() != 2) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + sal_Int16 nMonth = implGetDateMonth(rPar.Get(1)->GetDate()); + rPar.Get(0)->PutInteger(nMonth); } sal_Int16 implGetSecond( double dDate ) { - double nFrac = dDate - floor( dDate ); - nFrac *= 86400.0; - sal_Int32 nSeconds = static_cast<sal_Int32>(nFrac + 0.5); - sal_Int16 nTemp = static_cast<sal_Int16>(nSeconds / 3600); - nSeconds -= nTemp * 3600; - nTemp = static_cast<sal_Int16>(nSeconds / 60); - nSeconds -= nTemp * 60; + double nFrac = (dDate - floor(dDate)) * ::tools::Time::milliSecPerDay; + sal_uInt64 nMilliSeconds = static_cast<sal_uInt64>(nFrac + 0.5); + return static_cast<sal_Int16>((nMilliSeconds / ::tools::Time::milliSecPerSec) + % ::tools::Time::secondPerMinute); +} - sal_Int16 nRet = static_cast<sal_Int16>(nSeconds); - return nRet; +sal_Int32 implGetNanoSecond(double dDate) +{ + double nFrac = (dDate - floor(dDate)) * ::tools::Time::milliSecPerDay; + sal_uInt64 nMilliSeconds = static_cast<sal_uInt64>(nFrac + 0.5); + nMilliSeconds %= ::tools::Time::milliSecPerSec; + + return static_cast<sal_Int32>(nMilliSeconds * ::tools::Time ::nanoPerMilli); } void SbRtl_Second(StarBASIC *, SbxArray & rPar, bool) { - if (rPar.Count() < 2) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } - else - { - double nArg = rPar.Get(1)->GetDate(); - sal_Int16 nSecond = implGetSecond( nArg ); - rPar.Get(0)->PutInteger(nSecond); - } + if (rPar.Count() != 2) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + double nArg = rPar.Get(1)->GetDate(); + sal_Int16 nSecond = implGetSecond( nArg ); + rPar.Get(0)->PutInteger(nSecond); } double Now_Impl() { - DateTime aDateTime( DateTime::SYSTEM ); - double aSerial = static_cast<double>(GetDayDiff( aDateTime )); - tools::Long nSeconds = aDateTime.GetHour(); - nSeconds *= 3600; - nSeconds += aDateTime.GetMin() * 60; - nSeconds += aDateTime.GetSec(); - double nDays = static_cast<double>(nSeconds) / (24.0*3600.0); - aSerial += nDays; - return aSerial; + // tdf#161469 - align implementation with the now function in calc, i.e., include subseconds + DateTime aActTime(DateTime::SYSTEM); + return static_cast<double>(GetDayDiff(aActTime)) + + implTimeSerial(aActTime.GetHour(), aActTime.GetMin(), aActTime.GetSec(), + nanoSecToMilliSec(aActTime.GetNanoSec())); } // Date Now() -void SbRtl_Now(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutDate(Now_Impl()); } +void SbRtl_Now(StarBASIC*, SbxArray& rPar, bool) +{ + if (rPar.Count() != 1) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + rPar.Get(0)->PutDate(Now_Impl()); +} // Date Time() @@ -2263,6 +2073,11 @@ void SbRtl_Time(StarBASIC *, SbxArray & rPar, bool bWrite) { tools::Time aTime( tools::Time::SYSTEM ); SbxVariable* pMeth = rPar.Get(0); + if (!pMeth->IsString()) + { + pMeth->PutDate(aTime.GetTimeInDays()); + return; + } OUString aRes; if( pMeth->IsFixed() ) { @@ -2357,176 +2172,144 @@ void SbRtl_Date(StarBASIC *, SbxArray & rPar, bool bWrite) void SbRtl_IsArray(StarBASIC *, SbxArray & rPar, bool) { - if (rPar.Count() < 2) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } - else - { - rPar.Get(0)->PutBool((rPar.Get(1)->GetType() & SbxARRAY) != 0); - } + if (rPar.Count() != 2) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + rPar.Get(0)->PutBool((rPar.Get(1)->GetType() & SbxARRAY) != 0); } void SbRtl_IsObject(StarBASIC *, SbxArray & rPar, bool) { - if (rPar.Count() < 2) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } - else - { - SbxVariable* pVar = rPar.Get(1); - bool bObject = pVar->IsObject(); - SbxBase* pObj = (bObject ? pVar->GetObject() : nullptr); + if (rPar.Count() != 2) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - if( auto pUnoClass = dynamic_cast<SbUnoClass*>( pObj) ) - { - bObject = pUnoClass->getUnoClass().is(); - } - rPar.Get(0)->PutBool(bObject); + SbxVariable* pVar = rPar.Get(1); + bool bObject = pVar->IsObject(); + SbxBase* pObj = (bObject ? pVar->GetObject() : nullptr); + + if( auto pUnoClass = dynamic_cast<SbUnoClass*>( pObj) ) + { + bObject = pUnoClass->getUnoClass().is(); } + rPar.Get(0)->PutBool(bObject); } void SbRtl_IsDate(StarBASIC *, SbxArray & rPar, bool) { - if (rPar.Count() < 2) + if (rPar.Count() != 2) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + // #46134 only string is converted, all other types result in sal_False + SbxVariableRef xArg = rPar.Get(1); + SbxDataType eType = xArg->GetType(); + bool bDate = false; + + if( eType == SbxDATE ) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + bDate = true; } - else + else if( eType == SbxSTRING ) { - // #46134 only string is converted, all other types result in sal_False - SbxVariableRef xArg = rPar.Get(1); - SbxDataType eType = xArg->GetType(); - bool bDate = false; - - if( eType == SbxDATE ) - { - bDate = true; - } - else if( eType == SbxSTRING ) - { - ErrCode nPrevError = SbxBase::GetError(); - SbxBase::ResetError(); + ErrCode nPrevError = SbxBase::GetError(); + SbxBase::ResetError(); - // force conversion of the parameter to SbxDATE - xArg->SbxValue::GetDate(); + // force conversion of the parameter to SbxDATE + xArg->SbxValue::GetDate(); - bDate = !SbxBase::IsError(); + bDate = !SbxBase::IsError(); - SbxBase::ResetError(); - SbxBase::SetError( nPrevError ); - } - rPar.Get(0)->PutBool(bDate); + SbxBase::ResetError(); + SbxBase::SetError( nPrevError ); } + rPar.Get(0)->PutBool(bDate); } void SbRtl_IsEmpty(StarBASIC *, SbxArray & rPar, bool) { - if (rPar.Count() < 2) + if (rPar.Count() != 2) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + SbxVariable* pVar = nullptr; + if( SbiRuntime::isVBAEnabled() ) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + pVar = getDefaultProp(rPar.Get(1)); + } + if ( pVar ) + { + pVar->Broadcast( SfxHintId::BasicDataWanted ); + rPar.Get(0)->PutBool(pVar->IsEmpty()); } else { - SbxVariable* pVar = nullptr; - if( SbiRuntime::isVBAEnabled() ) - { - pVar = getDefaultProp(rPar.Get(1)); - } - if ( pVar ) - { - pVar->Broadcast( SfxHintId::BasicDataWanted ); - rPar.Get(0)->PutBool(pVar->IsEmpty()); - } - else - { - rPar.Get(0)->PutBool(rPar.Get(1)->IsEmpty()); - } + rPar.Get(0)->PutBool(rPar.Get(1)->IsEmpty()); } } void SbRtl_IsError(StarBASIC *, SbxArray & rPar, bool) { - if (rPar.Count() < 2) + if (rPar.Count() != 2) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + SbxVariable* pVar = rPar.Get(1); + SbUnoObject* pObj = dynamic_cast<SbUnoObject*>( pVar ); + if ( !pObj ) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + if ( SbxBase* pBaseObj = (pVar->IsObject() ? pVar->GetObject() : nullptr) ) + { + pObj = dynamic_cast<SbUnoObject*>( pBaseObj ); + } + } + uno::Reference< script::XErrorQuery > xError; + if ( pObj ) + { + xError.set( pObj->getUnoAny(), uno::UNO_QUERY ); + } + if ( xError.is() ) + { + rPar.Get(0)->PutBool(xError->hasError()); } else { - SbxVariable* pVar = rPar.Get(1); - SbUnoObject* pObj = dynamic_cast<SbUnoObject*>( pVar ); - if ( !pObj ) - { - if ( SbxBase* pBaseObj = (pVar->IsObject() ? pVar->GetObject() : nullptr) ) - { - pObj = dynamic_cast<SbUnoObject*>( pBaseObj ); - } - } - uno::Reference< script::XErrorQuery > xError; - if ( pObj ) - { - xError.set( pObj->getUnoAny(), uno::UNO_QUERY ); - } - if ( xError.is() ) - { - rPar.Get(0)->PutBool(xError->hasError()); - } - else - { - rPar.Get(0)->PutBool(rPar.Get(1)->IsErr()); - } + rPar.Get(0)->PutBool(rPar.Get(1)->IsErr()); } } void SbRtl_IsNull(StarBASIC *, SbxArray & rPar, bool) { - if (rPar.Count() < 2) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } - else + if (rPar.Count() != 2) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + // #51475 because of Uno-objects return true + // even if the pObj value is NULL + SbxVariableRef pArg = rPar.Get(1); + bool bNull = rPar.Get(1)->IsNull(); + if( !bNull && pArg->GetType() == SbxOBJECT ) { - // #51475 because of Uno-objects return true - // even if the pObj value is NULL - SbxVariableRef pArg = rPar.Get(1); - bool bNull = rPar.Get(1)->IsNull(); - if( !bNull && pArg->GetType() == SbxOBJECT ) + SbxBase* pObj = pArg->GetObject(); + if( !pObj ) { - SbxBase* pObj = pArg->GetObject(); - if( !pObj ) - { - bNull = true; - } + bNull = true; } - rPar.Get(0)->PutBool(bNull); } + rPar.Get(0)->PutBool(bNull); } void SbRtl_IsNumeric(StarBASIC *, SbxArray & rPar, bool) { - if (rPar.Count() < 2) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } - else - { - rPar.Get(0)->PutBool(rPar.Get(1)->IsNumericRTL()); - } + if (rPar.Count() != 2) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + rPar.Get(0)->PutBool(rPar.Get(1)->IsNumericRTL()); } void SbRtl_IsMissing(StarBASIC *, SbxArray & rPar, bool) { - if (rPar.Count() < 2) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } - else - { - // #57915 Missing is reported by an error - rPar.Get(0)->PutBool(rPar.Get(1)->IsErr()); - } + if (rPar.Count() != 2) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + // #57915 Missing is reported by an error + rPar.Get(0)->PutBool(rPar.Get(1)->IsErr()); } // Function looks for wildcards, removes them and always returns the pure path @@ -2537,7 +2320,7 @@ static OUString implSetupWildcard(const OUString& rFileParam, SbiRTLData& rRTLDa static const char cWild1 = '*'; static const char cWild2 = '?'; - rRTLData.pWildCard.reset(); + rRTLData.moWildCard.reset(); rRTLData.sFullNameToBeChecked.clear(); OUString aFileParam = rFileParam; @@ -2591,7 +2374,7 @@ static OUString implSetupWildcard(const OUString& rFileParam, SbiRTLData& rRTLDa // invalid anyway because it was not accepted by OSL before if (aPureFileName != "*") { - rRTLData.pWildCard = std::make_unique<WildCard>(aPureFileName); + rRTLData.moWildCard.emplace(aPureFileName); } return aPathStr; } @@ -2600,15 +2383,15 @@ static bool implCheckWildcard(std::u16string_view rName, SbiRTLData const& rRTLD { bool bMatch = true; - if (rRTLData.pWildCard) + if (rRTLData.moWildCard) { - bMatch = rRTLData.pWildCard->Matches(rName); + bMatch = rRTLData.moWildCard->Matches(rName); } return bMatch; } -static bool isRootDir( const OUString& aDirURLStr ) +static bool isRootDir( std::u16string_view aDirURLStr ) { INetURLObject aDirURLObj( aDirURLStr ); bool bRoot = false; @@ -2690,18 +2473,17 @@ void SbRtl_Dir(StarBASIC *, SbxArray & rPar, bool) } else { - rPar.Get(0)->PutString(""); + rPar.Get(0)->PutString(u""_ustr); } - SbAttributes nFlags = SbAttributes::NONE; + sal_Int16 nFlags = SbAttributes::NORMAL; if ( nParCount > 2 ) { - rRTLData.nDirFlags = nFlags - = static_cast<SbAttributes>(rPar.Get(2)->GetInteger()); + rRTLData.nDirFlags = nFlags = rPar.Get(2)->GetInteger(); } else { - rRTLData.nDirFlags = SbAttributes::NONE; + rRTLData.nDirFlags = SbAttributes::NORMAL; } // Read directory bool bIncludeFolders = bool(nFlags & SbAttributes::DIRECTORY); @@ -2809,15 +2591,14 @@ void SbRtl_Dir(StarBASIC *, SbxArray & rPar, bool) OUString aDirURL = implSetupWildcard(aFileParam, rRTLData); - SbAttributes nFlags = SbAttributes::NONE; + sal_Int16 nFlags = SbAttributes::NORMAL; if ( nParCount > 2 ) { - rRTLData.nDirFlags = nFlags - = static_cast<SbAttributes>(rPar.Get(2)->GetInteger()); + rRTLData.nDirFlags = nFlags = rPar.Get(2)->GetInteger(); } else { - rRTLData.nDirFlags = SbAttributes::NONE; + rRTLData.nDirFlags = SbAttributes::NORMAL; } // Read directory @@ -2918,7 +2699,7 @@ void SbRtl_GetAttr(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() == 2) { - sal_Int16 nFlags = 0; + sal_Int16 nFlags = SbAttributes::NORMAL; // In Windows, we want to use Windows API to get the file attributes // for VBA interoperability. @@ -2960,8 +2741,7 @@ void SbRtl_GetAttr(StarBASIC *, SbxArray & rPar, bool) catch(const Exception & ) {} if( !bExists ) { - StarBASIC::Error( ERRCODE_BASIC_FILE_NOT_FOUND ); - return; + return StarBASIC::Error( ERRCODE_BASIC_FILE_NOT_FOUND ); } bool bReadOnly = xSFI->isReadOnly( aPath ); @@ -2969,15 +2749,15 @@ void SbRtl_GetAttr(StarBASIC *, SbxArray & rPar, bool) bool bDirectory = xSFI->isFolder( aPath ); if( bReadOnly ) { - nFlags |= sal_uInt16(SbAttributes::READONLY); + nFlags |= SbAttributes::READONLY; } if( bHidden ) { - nFlags |= sal_uInt16(SbAttributes::HIDDEN); + nFlags |= SbAttributes::HIDDEN; } if( bDirectory ) { - nFlags |= sal_uInt16(SbAttributes::DIRECTORY); + nFlags |= SbAttributes::DIRECTORY; } } catch(const Exception & ) @@ -2999,11 +2779,11 @@ void SbRtl_GetAttr(StarBASIC *, SbxArray & rPar, bool) bool bDirectory = isFolder( aType ); if( bReadOnly ) { - nFlags |= sal_uInt16(SbAttributes::READONLY); + nFlags |= SbAttributes::READONLY; } if( bDirectory ) { - nFlags |= sal_uInt16(SbAttributes::DIRECTORY); + nFlags |= SbAttributes::DIRECTORY; } } rPar.Get(0)->PutInteger(nFlags); @@ -3128,8 +2908,7 @@ void SbRtl_EOF(StarBASIC *, SbxArray & rPar, bool) SbiStream* pSbStrm = pIO->GetStream( nChannel ); if ( !pSbStrm ) { - StarBASIC::Error( ERRCODE_BASIC_BAD_CHANNEL ); - return; + return StarBASIC::Error( ERRCODE_BASIC_BAD_CHANNEL ); } bool beof; SvStream* pSvStrm = pSbStrm->GetStrm(); @@ -3169,8 +2948,7 @@ void SbRtl_FileAttr(StarBASIC *, SbxArray & rPar, bool) SbiStream* pSbStrm = pIO->GetStream( nChannel ); if ( !pSbStrm ) { - StarBASIC::Error( ERRCODE_BASIC_BAD_CHANNEL ); - return; + return StarBASIC::Error( ERRCODE_BASIC_BAD_CHANNEL ); } sal_Int16 nRet; if (rPar.Get(2)->GetInteger() == 1) @@ -3198,8 +2976,7 @@ void SbRtl_Loc(StarBASIC *, SbxArray & rPar, bool) SbiStream* pSbStrm = pIO->GetStream( nChannel ); if ( !pSbStrm ) { - StarBASIC::Error( ERRCODE_BASIC_BAD_CHANNEL ); - return; + return StarBASIC::Error( ERRCODE_BASIC_BAD_CHANNEL ); } SvStream* pSvStrm = pSbStrm->GetStrm(); std::size_t nPos; @@ -3243,8 +3020,7 @@ void SbRtl_Lof(StarBASIC *, SbxArray & rPar, bool) SbiStream* pSbStrm = pIO->GetStream( nChannel ); if ( !pSbStrm ) { - StarBASIC::Error( ERRCODE_BASIC_BAD_CHANNEL ); - return; + return StarBASIC::Error( ERRCODE_BASIC_BAD_CHANNEL ); } SvStream* pSvStrm = pSbStrm->GetStrm(); sal_uInt64 const nLen = pSvStrm->TellEnd(); @@ -3259,16 +3035,14 @@ void SbRtl_Seek(StarBASIC *, SbxArray & rPar, bool) int nArgs = static_cast<int>(rPar.Count()); if ( nArgs < 2 || nArgs > 3 ) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); } sal_Int16 nChannel = rPar.Get(1)->GetInteger(); SbiIoSystem* pIO = GetSbData()->pInst->GetIoSystem(); SbiStream* pSbStrm = pIO->GetStream( nChannel ); if ( !pSbStrm ) { - StarBASIC::Error( ERRCODE_BASIC_BAD_CHANNEL ); - return; + return StarBASIC::Error( ERRCODE_BASIC_BAD_CHANNEL ); } SvStream* pStrm = pSbStrm->GetStrm(); @@ -3287,8 +3061,7 @@ void SbRtl_Seek(StarBASIC *, SbxArray & rPar, bool) sal_Int32 nPos = rPar.Get(2)->GetLong(); if ( nPos < 1 ) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); } nPos--; // Basic counts from 1, SvStreams count from 0 pSbStrm->SetExpandOnWriteTo( 0 ); @@ -3324,14 +3097,34 @@ void SbRtl_Format(StarBASIC *, SbxArray & rPar, bool) } } -// https://msdn.microsoft.com/en-us/vba/language-reference-vba/articles/formatnumber-function -void SbRtl_FormatNumber(StarBASIC*, SbxArray& rPar, bool) +static bool IsMissing(SbxArray& rPar, const sal_uInt32 i) +{ + const sal_uInt32 nArgCount = rPar.Count(); + if (nArgCount <= i) + return true; + + SbxVariable* aPar = rPar.Get(i); + return (aPar->GetType() == SbxERROR && SbiRuntime::IsMissing(aPar, 1)); +} + +static sal_Int16 GetOptionalIntegerParamOrDefault(SbxArray& rPar, const sal_uInt32 i, + const sal_Int16 defaultValue) +{ + return IsMissing(rPar, i) ? defaultValue : rPar.Get(i)->GetInteger(); +} + +static OUString GetOptionalOUStringParamOrDefault(SbxArray& rPar, const sal_uInt32 i, + const OUString& defaultValue) +{ + return IsMissing(rPar, i) ? defaultValue : rPar.Get(i)->GetOUString(); +} + +static void lcl_FormatNumberPercent(SbxArray& rPar, bool isPercent) { const sal_uInt32 nArgCount = rPar.Count(); if (nArgCount < 2 || nArgCount > 6) { - StarBASIC::Error(ERRCODE_BASIC_BAD_ARGUMENT); - return; + return StarBASIC::Error(ERRCODE_BASIC_BAD_ARGUMENT); } // The UI locale never changes -> we can use static value here @@ -3342,8 +3135,7 @@ void SbRtl_FormatNumber(StarBASIC*, SbxArray& rPar, bool) nNumDigitsAfterDecimal = rPar.Get(2)->GetInteger(); if (nNumDigitsAfterDecimal < -1) { - StarBASIC::Error(ERRCODE_BASIC_BAD_ARGUMENT); - return; + return StarBASIC::Error(ERRCODE_BASIC_BAD_ARGUMENT); } else if (nNumDigitsAfterDecimal > 255) nNumDigitsAfterDecimal %= 256; @@ -3366,8 +3158,7 @@ void SbRtl_FormatNumber(StarBASIC*, SbxArray& rPar, bool) // do nothing; break; default: - StarBASIC::Error(ERRCODE_BASIC_BAD_ARGUMENT); - return; + return StarBASIC::Error(ERRCODE_BASIC_BAD_ARGUMENT); } } @@ -3384,8 +3175,7 @@ void SbRtl_FormatNumber(StarBASIC*, SbxArray& rPar, bool) bUseParensForNegativeNumbers = true; break; default: - StarBASIC::Error(ERRCODE_BASIC_BAD_ARGUMENT); - return; + return StarBASIC::Error(ERRCODE_BASIC_BAD_ARGUMENT); } } @@ -3402,53 +3192,59 @@ void SbRtl_FormatNumber(StarBASIC*, SbxArray& rPar, bool) bGroupDigits = true; break; default: - StarBASIC::Error(ERRCODE_BASIC_BAD_ARGUMENT); - return; + return StarBASIC::Error(ERRCODE_BASIC_BAD_ARGUMENT); } } double fVal = rPar.Get(1)->GetDouble(); + if (isPercent) + fVal *= 100; const bool bNegative = fVal < 0; if (bNegative) fVal = fabs(fVal); // Always work with non-negatives, to easily handle leading zero static const sal_Unicode decSep = localeData.getNumDecimalSep().toChar(); - OUString aResult = rtl::math::doubleToUString( + OUStringBuffer aResult; + rtl::math::doubleToUStringBuffer(aResult, fVal, rtl_math_StringFormat_F, nNumDigitsAfterDecimal, decSep, bGroupDigits ? localeData.getDigitGrouping().getConstArray() : nullptr, localeData.getNumThousandSep().toChar()); - if (!bIncludeLeadingDigit && aResult.getLength() > 1 && aResult.startsWith("0")) - aResult = aResult.copy(1); + if (!bIncludeLeadingDigit && aResult.getLength() > 1) + aResult.stripStart('0'); if (nNumDigitsAfterDecimal > 0) { - sal_Int32 nActualDigits; const sal_Int32 nSepPos = aResult.indexOf(decSep); - if (nSepPos == -1) - nActualDigits = 0; - else - nActualDigits = aResult.getLength() - nSepPos - 1; // VBA allows up to 255 digits; rtl::math::doubleToUString outputs up to 15 digits // for ~small numbers, so pad them as appropriate. - if (nActualDigits < nNumDigitsAfterDecimal) - { - OUStringBuffer sBuf; - comphelper::string::padToLength(sBuf, nNumDigitsAfterDecimal - nActualDigits, '0'); - aResult += sBuf; - } + if (nSepPos >= 0) + comphelper::string::padToLength(aResult, nSepPos + nNumDigitsAfterDecimal + 1, '0'); } if (bNegative) { if (bUseParensForNegativeNumbers) - aResult = "(" + aResult + ")"; + aResult.insert(0, '(').append(')'); else - aResult = "-" + aResult; + aResult.insert(0, '-'); } + if (isPercent) + aResult.append('%'); + rPar.Get(0)->PutString(aResult.makeStringAndClear()); +} - rPar.Get(0)->PutString(aResult); +// https://docs.microsoft.com/en-us/office/vba/Language/Reference/User-Interface-Help/formatnumber-function +void SbRtl_FormatNumber(StarBASIC*, SbxArray& rPar, bool) +{ + return lcl_FormatNumberPercent(rPar, false); +} + +// https://docs.microsoft.com/en-us/office/vba/Language/Reference/User-Interface-Help/formatpercent-function +void SbRtl_FormatPercent(StarBASIC*, SbxArray& rPar, bool) +{ + return lcl_FormatNumberPercent(rPar, true); } namespace { @@ -3479,7 +3275,11 @@ struct RandomNumberGenerator } }; -class theRandomNumberGenerator : public rtl::Static<RandomNumberGenerator, theRandomNumberGenerator> {}; +RandomNumberGenerator& theRandomNumberGenerator() +{ + static RandomNumberGenerator theGenerator; + return theGenerator; +} } @@ -3492,7 +3292,7 @@ void SbRtl_Randomize(StarBASIC *, SbxArray & rPar, bool) if (rPar.Count() == 2) { int nSeed = static_cast<int>(rPar.Get(1)->GetInteger()); - theRandomNumberGenerator::get().global_rng.seed(nSeed); + theRandomNumberGenerator().global_rng.seed(nSeed); } // without parameter, no need to do anything - RNG is seeded at first use } @@ -3506,7 +3306,7 @@ void SbRtl_Rnd(StarBASIC *, SbxArray & rPar, bool) else { std::uniform_real_distribution<double> dist(0.0, 1.0); - double const tmp(dist(theRandomNumberGenerator::get().global_rng)); + double const tmp(dist(theRandomNumberGenerator().global_rng)); rPar.Get(0)->PutDouble(tmp); } } @@ -3531,6 +3331,13 @@ void SbRtl_Shell(StarBASIC *, SbxArray & rPar, bool) } else { + // Just go straight to error in this case + if (comphelper::LibreOfficeKit::isActive()) + { + StarBASIC::Error(ERRCODE_BASIC_FILE_NOT_FOUND); + return; + } + oslProcessOption nOptions = osl_Process_SEARCHPATH | osl_Process_DETACHED; OUString aCmdLine = rPar.Get(1)->GetOUString(); @@ -3543,30 +3350,21 @@ void SbRtl_Shell(StarBASIC *, SbxArray & rPar, bool) aCmdLine += " " + tmp; } } - else if( aCmdLine.isEmpty() ) - { - // avoid special treatment (empty list) - aCmdLine += " "; - } sal_Int32 nLen = aCmdLine.getLength(); // #55735 if there are parameters, they have to be separated // #72471 also separate the single parameters std::vector<OUString> aTokenVector; - OUString aToken; - sal_Int32 i = 0; - sal_Unicode c; - while( i < nLen ) + for (sal_Int32 i = 0; i < nLen;) { - for ( ;; ++i ) + sal_Unicode c = aCmdLine[i]; + if (c == ' ' || c == '\t') { - c = aCmdLine[ i ]; - if ( c != ' ' && c != '\t' ) - { - break; - } + ++i; + continue; } + OUString aToken; if( c == '\"' || c == '\'' ) { sal_Int32 iFoundPos = aCmdLine.indexOf( c, i + 1 ); @@ -3605,6 +3403,9 @@ void SbRtl_Shell(StarBASIC *, SbxArray & rPar, bool) } // #55735 / #72471 end + if (aTokenVector.empty()) + return StarBASIC::Error(ERRCODE_BASIC_BAD_ARGUMENT); + sal_Int16 nWinStyle = 0; if( nArgCount >= 3 ) { @@ -3699,62 +3500,62 @@ void SbRtl_VarType(StarBASIC *, SbxArray & rPar, bool) } // Exported function -OUString getBasicTypeName( SbxDataType eType ) -{ - static const char* pTypeNames[] = - { - "Empty", // SbxEMPTY - "Null", // SbxNULL - "Integer", // SbxINTEGER - "Long", // SbxLONG - "Single", // SbxSINGLE - "Double", // SbxDOUBLE - "Currency", // SbxCURRENCY - "Date", // SbxDATE - "String", // SbxSTRING - "Object", // SbxOBJECT - "Error", // SbxERROR - "Boolean", // SbxBOOL - "Variant", // SbxVARIANT - "DataObject", // SbxDATAOBJECT - "Unknown Type", - "Unknown Type", - "Char", // SbxCHAR - "Byte", // SbxBYTE - "UShort", // SbxUSHORT - "ULong", // SbxULONG - "Long64", // SbxLONG64 - "ULong64", // SbxULONG64 - "Int", // SbxINT - "UInt", // SbxUINT - "Void", // SbxVOID - "HResult", // SbxHRESULT - "Pointer", // SbxPOINTER - "DimArray", // SbxDIMARRAY - "CArray", // SbxCARRAY - "Userdef", // SbxUSERDEF - "Lpstr", // SbxLPSTR - "Lpwstr", // SbxLPWSTR - "Unknown Type", // SbxCoreSTRING - "WString", // SbxWSTRING - "WChar", // SbxWCHAR - "Int64", // SbxSALINT64 - "UInt64", // SbxSALUINT64 - "Decimal", // SbxDECIMAL +const OUString & getBasicTypeName( SbxDataType eType ) +{ + static constexpr OUString pTypeNames[] = + { + u"Empty"_ustr, // SbxEMPTY + u"Null"_ustr, // SbxNULL + u"Integer"_ustr, // SbxINTEGER + u"Long"_ustr, // SbxLONG + u"Single"_ustr, // SbxSINGLE + u"Double"_ustr, // SbxDOUBLE + u"Currency"_ustr, // SbxCURRENCY + u"Date"_ustr, // SbxDATE + u"String"_ustr, // SbxSTRING + u"Object"_ustr, // SbxOBJECT + u"Error"_ustr, // SbxERROR + u"Boolean"_ustr, // SbxBOOL + u"Variant"_ustr, // SbxVARIANT + u"DataObject"_ustr, // SbxDATAOBJECT + u"Unknown Type"_ustr, + u"Unknown Type"_ustr, + u"Char"_ustr, // SbxCHAR + u"Byte"_ustr, // SbxBYTE + u"UShort"_ustr, // SbxUSHORT + u"ULong"_ustr, // SbxULONG + u"Long64"_ustr, // SbxLONG64 + u"ULong64"_ustr, // SbxULONG64 + u"Int"_ustr, // SbxINT + u"UInt"_ustr, // SbxUINT + u"Void"_ustr, // SbxVOID + u"HResult"_ustr, // SbxHRESULT + u"Pointer"_ustr, // SbxPOINTER + u"DimArray"_ustr, // SbxDIMARRAY + u"CArray"_ustr, // SbxCARRAY + u"Userdef"_ustr, // SbxUSERDEF + u"Lpstr"_ustr, // SbxLPSTR + u"Lpwstr"_ustr, // SbxLPWSTR + u"Unknown Type"_ustr, // SbxCoreSTRING + u"WString"_ustr, // SbxWSTRING + u"WChar"_ustr, // SbxWCHAR + u"Int64"_ustr, // SbxSALINT64 + u"UInt64"_ustr, // SbxSALUINT64 + u"Decimal"_ustr, // SbxDECIMAL }; size_t nPos = static_cast<size_t>(eType) & 0x0FFF; - const size_t nTypeNameCount = SAL_N_ELEMENTS( pTypeNames ); + const size_t nTypeNameCount = std::size( pTypeNames ); if ( nPos >= nTypeNameCount ) { nPos = nTypeNameCount - 1; } - return OUString::createFromAscii(pTypeNames[nPos]); + return pTypeNames[nPos]; } static OUString getObjectTypeName( SbxVariable* pVar ) { - OUString sRet( "Object" ); + OUString sRet( u"Object"_ustr ); if ( pVar ) { SbxBase* pBaseObj = pVar->GetObject(); @@ -3796,7 +3597,7 @@ static OUString getObjectTypeName( SbxVariable* pVar ) { try { - xInv->getValue( "$GetTypeName" ) >>= sRet; + xInv->getValue( u"$GetTypeName"_ustr ) >>= sRet; } catch(const Exception& ) { @@ -3846,14 +3647,9 @@ void SbRtl_TypeName(StarBASIC *, SbxArray & rPar, bool) void SbRtl_Len(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() != 2) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } - else - { - const OUString& rStr = rPar.Get(1)->GetOUString(); - rPar.Get(0)->PutLong(rStr.getLength()); - } + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + const OUString aStr = rPar.Get(1)->GetOUString(); + rPar.Get(0)->PutLong(aStr.getLength()); } void SbRtl_DDEInitiate(StarBASIC *, SbxArray & rPar, bool) @@ -3861,15 +3657,14 @@ void SbRtl_DDEInitiate(StarBASIC *, SbxArray & rPar, bool) int nArgs = static_cast<int>(rPar.Count()); if ( nArgs != 3 ) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); } - const OUString& rApp = rPar.Get(1)->GetOUString(); - const OUString& rTopic = rPar.Get(2)->GetOUString(); + const OUString aApp = rPar.Get(1)->GetOUString(); + const OUString aTopic = rPar.Get(2)->GetOUString(); SbiDdeControl* pDDE = GetSbData()->pInst->GetDdeControl(); size_t nChannel; - ErrCode nDdeErr = pDDE->Initiate( rApp, rTopic, nChannel ); + ErrCode nDdeErr = pDDE->Initiate( aApp, aTopic, nChannel ); if( nDdeErr ) { StarBASIC::Error( nDdeErr ); @@ -3904,8 +3699,7 @@ void SbRtl_DDETerminateAll(StarBASIC *, SbxArray & rPar, bool) int nArgs = static_cast<int>(rPar.Count()); if ( nArgs != 1 ) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); } SbiDdeControl* pDDE = GetSbData()->pInst->GetDdeControl(); @@ -3921,14 +3715,13 @@ void SbRtl_DDERequest(StarBASIC *, SbxArray & rPar, bool) int nArgs = static_cast<int>(rPar.Count()); if ( nArgs != 3 ) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); } size_t nChannel = rPar.Get(1)->GetInteger(); - const OUString& rItem = rPar.Get(2)->GetOUString(); + const OUString aItem = rPar.Get(2)->GetOUString(); SbiDdeControl* pDDE = GetSbData()->pInst->GetDdeControl(); OUString aResult; - ErrCode nDdeErr = pDDE->Request( nChannel, rItem, aResult ); + ErrCode nDdeErr = pDDE->Request( nChannel, aItem, aResult ); if( nDdeErr ) { StarBASIC::Error( nDdeErr ); @@ -3945,13 +3738,12 @@ void SbRtl_DDEExecute(StarBASIC *, SbxArray & rPar, bool) int nArgs = static_cast<int>(rPar.Count()); if ( nArgs != 3 ) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); } size_t nChannel = rPar.Get(1)->GetInteger(); - const OUString& rCommand = rPar.Get(2)->GetOUString(); + const OUString aCommand = rPar.Get(2)->GetOUString(); SbiDdeControl* pDDE = GetSbData()->pInst->GetDdeControl(); - ErrCode nDdeErr = pDDE->Execute( nChannel, rCommand ); + ErrCode nDdeErr = pDDE->Execute( nChannel, aCommand ); if( nDdeErr ) { StarBASIC::Error( nDdeErr ); @@ -3964,14 +3756,13 @@ void SbRtl_DDEPoke(StarBASIC *, SbxArray & rPar, bool) int nArgs = static_cast<int>(rPar.Count()); if ( nArgs != 4 ) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); } size_t nChannel = rPar.Get(1)->GetInteger(); - const OUString& rItem = rPar.Get(2)->GetOUString(); - const OUString& rData = rPar.Get(3)->GetOUString(); + const OUString aItem = rPar.Get(2)->GetOUString(); + const OUString aData = rPar.Get(3)->GetOUString(); SbiDdeControl* pDDE = GetSbData()->pInst->GetDdeControl(); - ErrCode nDdeErr = pDDE->Poke( nChannel, rItem, rData ); + ErrCode nDdeErr = pDDE->Poke( nChannel, aItem, aData ); if( nDdeErr ) { StarBASIC::Error( nDdeErr ); @@ -3983,8 +3774,7 @@ void SbRtl_FreeFile(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() != 1) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); } SbiIoSystem* pIO = GetSbData()->pInst->GetIoSystem(); short nChannel = 1; @@ -4005,56 +3795,42 @@ void SbRtl_LBound(StarBASIC *, SbxArray & rPar, bool) { const sal_uInt32 nParCount = rPar.Count(); if ( nParCount != 3 && nParCount != 2 ) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; - } + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + SbxBase* pParObj = rPar.Get(1)->GetObject(); SbxDimArray* pArr = dynamic_cast<SbxDimArray*>( pParObj ); - if( pArr ) - { - sal_Int32 nLower, nUpper; - short nDim = (nParCount == 3) ? static_cast<short>(rPar.Get(2)->GetInteger()) : 1; - if (!pArr->GetDim(nDim, nLower, nUpper)) - StarBASIC::Error( ERRCODE_BASIC_OUT_OF_RANGE ); - else - rPar.Get(0)->PutLong(nLower); - } - else - StarBASIC::Error( ERRCODE_BASIC_MUST_HAVE_DIMS ); + if( !pArr ) + return StarBASIC::Error( ERRCODE_BASIC_MUST_HAVE_DIMS ); + + sal_Int32 nLower, nUpper; + short nDim = (nParCount == 3) ? static_cast<short>(rPar.Get(2)->GetInteger()) : 1; + if (!pArr->GetDim(nDim, nLower, nUpper)) + return StarBASIC::Error( ERRCODE_BASIC_OUT_OF_RANGE ); + rPar.Get(0)->PutLong(nLower); } void SbRtl_UBound(StarBASIC *, SbxArray & rPar, bool) { const sal_uInt32 nParCount = rPar.Count(); if ( nParCount != 3 && nParCount != 2 ) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; - } + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); SbxBase* pParObj = rPar.Get(1)->GetObject(); SbxDimArray* pArr = dynamic_cast<SbxDimArray*>( pParObj ); - if( pArr ) - { - sal_Int32 nLower, nUpper; - short nDim = (nParCount == 3) ? static_cast<short>(rPar.Get(2)->GetInteger()) : 1; - if (!pArr->GetDim(nDim, nLower, nUpper)) - StarBASIC::Error( ERRCODE_BASIC_OUT_OF_RANGE ); - else - rPar.Get(0)->PutLong(nUpper); - } - else - StarBASIC::Error( ERRCODE_BASIC_MUST_HAVE_DIMS ); + if( !pArr ) + return StarBASIC::Error( ERRCODE_BASIC_MUST_HAVE_DIMS ); + + sal_Int32 nLower, nUpper; + short nDim = (nParCount == 3) ? static_cast<short>(rPar.Get(2)->GetInteger()) : 1; + if (!pArr->GetDim(nDim, nLower, nUpper)) + return StarBASIC::Error( ERRCODE_BASIC_OUT_OF_RANGE ); + rPar.Get(0)->PutLong(nUpper); } void SbRtl_RGB(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() != 4) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; - } + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); sal_Int32 nRed = rPar.Get(1)->GetInteger() & 0xFF; sal_Int32 nGreen = rPar.Get(2)->GetInteger() & 0xFF; @@ -4103,31 +3879,61 @@ void SbRtl_QBColor(StarBASIC *, SbxArray & rPar, bool) if (rPar.Count() != 2) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); } sal_Int16 nCol = rPar.Get(1)->GetInteger(); if( nCol < 0 || nCol > 15 ) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); } sal_Int32 nRGB = pRGB[ nCol ]; rPar.Get(0)->PutLong(nRGB); } +static std::vector<sal_uInt8> byteArray2Vec(SbxArray* pArr) +{ + std::vector<sal_uInt8> result; + if (pArr) + { + const sal_uInt32 nCount = pArr->Count(); + result.reserve(nCount + 1); // to avoid reallocation when padding in vbFromUnicode + for (sal_uInt32 i = 0; i < nCount; i++) + result.push_back(pArr->Get(i)->GetByte()); + } + return result; +} + +// Makes sure to get the byte array if passed, or the string converted to the bytes using +// StringToByteArray in basic/source/sbx/sbxstr.cxx +static std::vector<sal_uInt8> getByteArray(const SbxValue& val) +{ + if (val.GetFullType() == SbxOBJECT) + if (auto pObj = val.GetObject()) + if (pObj->GetType() == (SbxARRAY | SbxBYTE)) + if (auto pArr = dynamic_cast<SbxArray*>(pObj)) + return byteArray2Vec(pArr); + + // Convert to string + tools::SvRef<SbxValue> pStringValue(new SbxValue(SbxSTRING)); + *pStringValue = val; + + // Convert string to byte array + tools::SvRef<SbxValue> pValue(new SbxValue(SbxOBJECT)); + pValue->PutObject(new SbxArray(SbxBYTE)); + *pValue = *pStringValue; // Does the magic of conversion of strings to byte arrays + return byteArray2Vec(dynamic_cast<SbxArray*>(pValue->GetObject())); +} + // StrConv(string, conversion, LCID) void SbRtl_StrConv(StarBASIC *, SbxArray & rPar, bool) { const sal_uInt32 nArgCount = rPar.Count() - 1; if( nArgCount < 2 || nArgCount > 3 ) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); } - OUString aOldStr = rPar.Get(1)->GetOUString(); sal_Int32 nConversion = rPar.Get(2)->GetLong(); LanguageType nLanguage = LANGUAGE_SYSTEM; if (nArgCount == 3) @@ -4135,127 +3941,101 @@ void SbRtl_StrConv(StarBASIC *, SbxArray & rPar, bool) sal_Int32 lcid = rPar.Get(3)->GetLong(); nLanguage = LanguageType(lcid); } - OUString sLanguage = LanguageTag(nLanguage).getLanguage(); - rtl_TextEncoding encodingVal = utl_getWinTextEncodingFromLangStr(sLanguage); - sal_Int32 nOldLen = aOldStr.getLength(); - if( nOldLen == 0 ) + if (nConversion == ooo::vba::VbStrConv::vbUnicode) // This mode does not combine { - // null string,return - rPar.Get(0)->PutString(aOldStr); + // Assume that the passed byte array is encoded in the defined encoding, convert to + // UTF-16 and store as string. Passed strings are converted to byte array first. + auto inArray = getByteArray(*rPar.Get(1)); + std::string_view s(reinterpret_cast<char*>(inArray.data()), inArray.size() / sizeof(char)); + const auto encoding = utl_getWinTextEncodingFromLangStr(LanguageTag(nLanguage).getBcp47()); + OUString aOUStr = OStringToOUString(s, encoding); + rPar.Get(0)->PutString(aOUStr); return; } - TransliterationFlags nType = TransliterationFlags::NONE; - if ( (nConversion & 0x03) == 3 ) // vbProperCase - { - const CharClass& rCharClass = GetCharClass(); - aOldStr = rCharClass.titlecase( aOldStr.toAsciiLowerCase(), 0, nOldLen ); - } - else if ( (nConversion & 0x01) == 1 ) // vbUpperCase - { - nType |= TransliterationFlags::LOWERCASE_UPPERCASE; - } - else if ( (nConversion & 0x02) == 2 ) // vbLowerCase - { - nType |= TransliterationFlags::UPPERCASE_LOWERCASE; - } - if ( (nConversion & 0x04) == 4 ) // vbWide - { - nType |= TransliterationFlags::HALFWIDTH_FULLWIDTH; - } - else if ( (nConversion & 0x08) == 8 ) // vbNarrow - { - nType |= TransliterationFlags::FULLWIDTH_HALFWIDTH; - } - if ( (nConversion & 0x10) == 16) // vbKatakana - { - nType |= TransliterationFlags::HIRAGANA_KATAKANA; - } - else if ( (nConversion & 0x20) == 32 ) // vbHiragana - { - nType |= TransliterationFlags::KATAKANA_HIRAGANA; - } - OUString aNewStr( aOldStr ); - if( nType != TransliterationFlags::NONE ) + if (nConversion == ooo::vba::VbStrConv::vbFromUnicode) // This mode does not combine { - uno::Reference< uno::XComponentContext > xContext = getProcessComponentContext(); - ::utl::TransliterationWrapper aTransliterationWrapper( xContext, nType ); - uno::Sequence<sal_Int32> aOffsets; - aTransliterationWrapper.loadModuleIfNeeded( nLanguage ); - aNewStr = aTransliterationWrapper.transliterate( aOldStr, nLanguage, 0, nOldLen, &aOffsets ); - } + // Assume that the passed byte array is UTF-16-encoded (system-endian), convert to specified + // encoding and store as byte array. Passed strings are converted to byte array first. + auto inArray = getByteArray(*rPar.Get(1)); + while (inArray.size() % sizeof(sal_Unicode)) + inArray.push_back('\0'); + std::u16string_view s(reinterpret_cast<sal_Unicode*>(inArray.data()), + inArray.size() / sizeof(sal_Unicode)); + const auto encoding = utl_getWinTextEncodingFromLangStr(LanguageTag(nLanguage).getBcp47()); + OString aOStr = OUStringToOString(s, encoding); + const sal_Int32 lb = IsBaseIndexOne() ? 1 : 0; + const sal_Int32 ub = lb + aOStr.getLength() - 1; + SbxDimArray* pArray = new SbxDimArray(SbxBYTE); + pArray->unoAddDim(lb, ub); - if ( (nConversion & 0x40) == 64 ) // vbUnicode - { - // convert the string to byte string, preserving unicode (2 bytes per character) - sal_Int32 nSize = aNewStr.getLength()*2; - const sal_Unicode* pSrc = aNewStr.getStr(); - std::unique_ptr<char[]> pChar(new char[nSize+1]); - for( sal_Int32 i=0; i < nSize; i++ ) + for (sal_Int32 i = 0; i < aOStr.getLength(); ++i) { - pChar[i] = static_cast< char >( (i%2) ? ((*pSrc) >> 8) & 0xff : (*pSrc) & 0xff ); - if( i%2 ) - { - pSrc++; - } + SbxVariable* pNew = new SbxVariable(SbxBYTE); + pNew->PutByte(aOStr[i]); + pArray->Put(pNew, i); } - pChar[nSize] = '\0'; - OString aOStr(pChar.get()); - // there is no concept about default codepage in unix. so it is incorrectly in unix - OUString aOUStr = OStringToOUString(aOStr, encodingVal); - rPar.Get(0)->PutString(aOUStr); + SbxVariable* retVar = rPar.Get(0); + SbxFlagBits nFlags = retVar->GetFlags(); + retVar->ResetFlag(SbxFlagBits::Fixed); + retVar->PutObject(pArray); + retVar->SetFlags(nFlags); + retVar->SetParameters(nullptr); return; } - else if ( (nConversion & 0x80) == 128 ) // vbFromUnicode + + std::vector<TransliterationFlags> aTranslitSet; + auto check = [&nConversion, &aTranslitSet](sal_Int32 conv, TransliterationFlags flag) { - // there is no concept about default codepage in unix. so it is incorrectly in unix - OString aOStr = OUStringToOString(aNewStr, encodingVal); - const char* pChar = aOStr.getStr(); - sal_Int32 nArraySize = aOStr.getLength(); - SbxDimArray* pArray = new SbxDimArray(SbxBYTE); - bool bIncIndex = IsBaseIndexOne(); - if(nArraySize) + if ((nConversion & conv) != conv) + return false; + + aTranslitSet.push_back(flag); + nConversion &= ~conv; + return true; + }; + + // Check mutually exclusive bits together + + if (!check(ooo::vba::VbStrConv::vbProperCase, TransliterationFlags::TITLE_CASE)) + if (!check(ooo::vba::VbStrConv::vbUpperCase, TransliterationFlags::LOWERCASE_UPPERCASE)) + check(ooo::vba::VbStrConv::vbLowerCase, TransliterationFlags::UPPERCASE_LOWERCASE); + + if (!check(ooo::vba::VbStrConv::vbWide, TransliterationFlags::HALFWIDTH_FULLWIDTH)) + check(ooo::vba::VbStrConv::vbNarrow, TransliterationFlags::FULLWIDTH_HALFWIDTH); + + if (!check(ooo::vba::VbStrConv::vbKatakana, TransliterationFlags::HIRAGANA_KATAKANA)) + check(ooo::vba::VbStrConv::vbHiragana, TransliterationFlags::KATAKANA_HIRAGANA); + + if (nConversion) // unknown / incorrectly combined bits + return StarBASIC::Error(ERRCODE_BASIC_BAD_ARGUMENT); + + OUString aStr = rPar.Get(1)->GetOUString(); + if (!aStr.isEmpty() && !aTranslitSet.empty()) + { + const uno::Reference< uno::XComponentContext >& xContext = getProcessComponentContext(); + + for (auto transliterationFlag : aTranslitSet) { - if( bIncIndex ) + if (transliterationFlag == TransliterationFlags::TITLE_CASE) { - pArray->AddDim(1, nArraySize); + // TransliterationWrapper only handles the first character of the passed string + // when handling TITLE_CASE; see Transliteration_titlecase::transliterateImpl in + // i18npool/source/transliteration/transliteration_body.cxx + CharClass aCharClass{ xContext, LanguageTag(nLanguage) }; + aStr = aCharClass.titlecase(aCharClass.lowercase(aStr)); } else { - pArray->AddDim(0, nArraySize - 1); - } - } - else - { - pArray->unoAddDim(0, -1); - } - - for( sal_Int32 i=0; i< nArraySize; i++) - { - SbxVariable* pNew = new SbxVariable( SbxBYTE ); - pNew->PutByte(*pChar); - pChar++; - pNew->SetFlag( SbxFlagBits::Write ); - sal_Int32 aIdx[1]; - aIdx[0] = i; - if( bIncIndex ) - { - ++aIdx[0]; + utl::TransliterationWrapper aWrapper(xContext, transliterationFlag); + aStr = aWrapper.transliterate(aStr, nLanguage, 0, aStr.getLength(), nullptr); } - pArray->Put(pNew, aIdx); } - - SbxVariableRef refVar = rPar.Get(0); - SbxFlagBits nFlags = refVar->GetFlags(); - refVar->ResetFlag( SbxFlagBits::Fixed ); - refVar->PutObject( pArray ); - refVar->SetFlags( nFlags ); - refVar->SetParameters( nullptr ); - return; } - rPar.Get(0)->PutString(aNewStr); + + rPar.Get(0)->PutString(aStr); } @@ -4263,8 +4043,7 @@ void SbRtl_Beep(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() != 1) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); } Sound::Beep(); } @@ -4273,8 +4052,7 @@ void SbRtl_Load(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() != 2) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); } @@ -4288,7 +4066,7 @@ void SbRtl_Load(StarBASIC *, SbxArray & rPar, bool) } else if (SbxObject* pSbxObj = dynamic_cast<SbxObject*>(pObj)) { - SbxVariable* pVar = pSbxObj->Find("Load", SbxClassType::Method); + SbxVariable* pVar = pSbxObj->Find(u"Load"_ustr, SbxClassType::Method); if( pVar ) { pVar->GetInteger(); @@ -4301,8 +4079,7 @@ void SbRtl_Unload(StarBASIC *, SbxArray & rPar, bool) rPar.Get(0)->PutEmpty(); if (rPar.Count() != 2) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); } @@ -4316,7 +4093,7 @@ void SbRtl_Unload(StarBASIC *, SbxArray & rPar, bool) } else if (SbxObject *pSbxObj = dynamic_cast<SbxObject*>(pObj)) { - SbxVariable* pVar = pSbxObj->Find("Unload", SbxClassType::Method); + SbxVariable* pVar = pSbxObj->Find(u"Unload"_ustr, SbxClassType::Method); if( pVar ) { pVar->GetInteger(); @@ -4328,8 +4105,7 @@ void SbRtl_LoadPicture(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() != 2) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); } OUString aFileURL = getFullPath(rPar.Get(1)->GetOUString()); @@ -4352,8 +4128,7 @@ void SbRtl_SavePicture(StarBASIC *, SbxArray & rPar, bool) rPar.Get(0)->PutEmpty(); if (rPar.Count() != 3) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); } SbxBase* pObj = rPar.Get(1)->GetObject(); @@ -4371,40 +4146,23 @@ void SbRtl_MsgBox(StarBASIC *, SbxArray & rPar, bool) const sal_uInt32 nArgCount = rPar.Count(); if( nArgCount < 2 || nArgCount > 6 ) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); } - WinBits nType = 0; // MB_OK - if( nArgCount >= 3 ) - nType = static_cast<WinBits>(rPar.Get(2)->GetInteger()); - WinBits nStyle = nType; - nStyle &= 15; // delete bits 4-16 - if (nStyle > 5) - nStyle = 0; - - enum BasicResponse - { - Ok = 1, - Cancel = 2, - Abort = 3, - Retry = 4, - Ignore = 5, - Yes = 6, - No = 7 - }; - OUString aMsg = rPar.Get(1)->GetOUString(); - OUString aTitle; - if( nArgCount >= 4 ) + // tdf#147529 - check for missing parameters + if (IsMissing(rPar, 1)) { - aTitle = rPar.Get(3)->GetOUString(); - } - else - { - aTitle = Application::GetDisplayName(); + return StarBASIC::Error(ERRCODE_BASIC_NOT_OPTIONAL); } - WinBits nDialogType = nType & (16+32+64); + // tdf#151012 - initialize optional parameters with their default values (number of buttons) + sal_Int16 nType = GetOptionalIntegerParamOrDefault(rPar, 2, SbMB::OK); + + OUString aMsg = rPar.Get(1)->GetOUString(); + // tdf#151012 - initialize optional parameters with their default values (title of dialog box) + OUString aTitle = GetOptionalOUStringParamOrDefault(rPar, 3, Application::GetDisplayName()); + + sal_Int16 nDialogType = nType & (SbMB::ICONSTOP | SbMB::ICONQUESTION | SbMB::ICONINFORMATION); SolarMutexGuard aSolarGuard; weld::Widget* pParent = Application::GetDefDialogParent(); @@ -4413,85 +4171,64 @@ void SbRtl_MsgBox(StarBASIC *, SbxArray & rPar, bool) switch (nDialogType) { - case 16: + case SbMB::ICONSTOP: eType = VclMessageType::Error; break; - case 32: + case SbMB::ICONQUESTION: eType = VclMessageType::Question; break; - case 48: + case SbMB::ICONEXCLAMATION: eType = VclMessageType::Warning; break; - case 64: + case SbMB::ICONINFORMATION: eType = VclMessageType::Info; break; } std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(pParent, - eType, VclButtonsType::NONE, aMsg)); + eType, VclButtonsType::NONE, aMsg, GetpApp())); - switch (nStyle) + std::vector<std::pair<StandardButtonType, sal_Int16>> buttons; + switch (nType & 0x0F) // delete bits 4-16 { - case 0: // MB_OK + case SbMB::OK: default: - xBox->add_button(GetStandardText(StandardButtonType::OK), BasicResponse::Ok); + buttons.emplace_back(StandardButtonType::OK, SbMB::Response::OK); break; - case 1: // MB_OKCANCEL - xBox->add_button(GetStandardText(StandardButtonType::OK), BasicResponse::Ok); - xBox->add_button(GetStandardText(StandardButtonType::Cancel), BasicResponse::Cancel); - - if (nType & 256 || nType & 512) - xBox->set_default_response(BasicResponse::Cancel); - else - xBox->set_default_response(BasicResponse::Ok); - + case SbMB::OKCANCEL: + buttons.emplace_back(StandardButtonType::OK, SbMB::Response::OK); + buttons.emplace_back(StandardButtonType::Cancel, SbMB::Response::CANCEL); break; - case 2: // MB_ABORTRETRYIGNORE - xBox->add_button(GetStandardText(StandardButtonType::Abort), BasicResponse::Abort); - xBox->add_button(GetStandardText(StandardButtonType::Retry), BasicResponse::Retry); - xBox->add_button(GetStandardText(StandardButtonType::Ignore), BasicResponse::Ignore); - - if (nType & 256) - xBox->set_default_response(BasicResponse::Retry); - else if (nType & 512) - xBox->set_default_response(BasicResponse::Ignore); - else - xBox->set_default_response(BasicResponse::Cancel); - + case SbMB::ABORTRETRYIGNORE: + buttons.emplace_back(StandardButtonType::Abort, SbMB::Response::ABORT); + buttons.emplace_back(StandardButtonType::Retry, SbMB::Response::RETRY); + buttons.emplace_back(StandardButtonType::Ignore, SbMB::Response::IGNORE); break; - case 3: // MB_YESNOCANCEL - xBox->add_button(GetStandardText(StandardButtonType::Yes), BasicResponse::Yes); - xBox->add_button(GetStandardText(StandardButtonType::No), BasicResponse::No); - xBox->add_button(GetStandardText(StandardButtonType::Cancel), BasicResponse::Cancel); - - if (nType & 256 || nType & 512) - xBox->set_default_response(BasicResponse::Cancel); - else - xBox->set_default_response(BasicResponse::Yes); - + case SbMB::YESNOCANCEL: + buttons.emplace_back(StandardButtonType::Yes, SbMB::Response::YES); + buttons.emplace_back(StandardButtonType::No, SbMB::Response::NO); + buttons.emplace_back(StandardButtonType::Cancel, SbMB::Response::CANCEL); break; - case 4: // MB_YESNO - xBox->add_button(GetStandardText(StandardButtonType::Yes), BasicResponse::Yes); - xBox->add_button(GetStandardText(StandardButtonType::No), BasicResponse::No); - - if (nType & 256 || nType & 512) - xBox->set_default_response(BasicResponse::No); - else - xBox->set_default_response(BasicResponse::Yes); - + case SbMB::YESNO: + buttons.emplace_back(StandardButtonType::Yes, SbMB::Response::YES); + buttons.emplace_back(StandardButtonType::No, SbMB::Response::NO); break; - case 5: // MB_RETRYCANCEL - xBox->add_button(GetStandardText(StandardButtonType::Retry), BasicResponse::Retry); - xBox->add_button(GetStandardText(StandardButtonType::Cancel), BasicResponse::Cancel); - - if (nType & 256 || nType & 512) - xBox->set_default_response(BasicResponse::Cancel); - else - xBox->set_default_response(BasicResponse::Retry); - + case SbMB::RETRYCANCEL: + buttons.emplace_back(StandardButtonType::Retry, SbMB::Response::RETRY); + buttons.emplace_back(StandardButtonType::Cancel, SbMB::Response::CANCEL); break; } + for (auto [buttonType, buttonResponse] : buttons) + xBox->add_button(GetStandardText(buttonType), buttonResponse); + + std::size_t default_button = 0; + if (nType & SbMB::DEFBUTTON2) + default_button = 1; + else if (nType & SbMB::DEFBUTTON3) + default_button = 2; + xBox->set_default_response(buttons[std::min(default_button, buttons.size() - 1)].second); + xBox->set_title(aTitle); sal_Int16 nRet = xBox->run(); rPar.Get(0)->PutInteger(nRet); @@ -4503,7 +4240,7 @@ void SbRtl_SetAttr(StarBASIC *, SbxArray & rPar, bool) if (rPar.Count() == 3) { OUString aStr = rPar.Get(1)->GetOUString(); - SbAttributes nFlags = static_cast<SbAttributes>(rPar.Get(2)->GetInteger()); + sal_Int16 nFlags = rPar.Get(2)->GetInteger(); if( hasUno() ) { @@ -4514,7 +4251,7 @@ void SbRtl_SetAttr(StarBASIC *, SbxArray & rPar, bool) { bool bReadOnly = bool(nFlags & SbAttributes::READONLY); xSFI->setReadOnly( aStr, bReadOnly ); - bool bHidden = bool(nFlags & SbAttributes::HIDDEN); + bool bHidden = bool(nFlags & SbAttributes::HIDDEN); xSFI->setHidden( aStr, bHidden ); } catch(const Exception & ) @@ -4609,8 +4346,7 @@ void SbRtl_Partition(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() != 5) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); } sal_Int32 nNumber = rPar.Get(1)->GetLong(); @@ -4620,8 +4356,7 @@ void SbRtl_Partition(StarBASIC *, SbxArray & rPar, bool) if( nStart < 0 || nStop <= nStart || nInterval < 1 ) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); } // the Partition function inserts leading spaces before lowervalue and uppervalue @@ -4687,28 +4422,10 @@ void SbRtl_Partition(StarBASIC *, SbxArray & rPar, bool) #endif -static tools::Long GetDayDiff( const Date& rDate ) -{ - Date aRefDate( 1,1,1900 ); - tools::Long nDiffDays; - if ( aRefDate > rDate ) - { - nDiffDays = aRefDate - rDate; - nDiffDays *= -1; - } - else - { - nDiffDays = rDate - aRefDate; - } - nDiffDays += 2; // adjustment VisualBasic: 1.Jan.1900 == 2 - return nDiffDays; -} - sal_Int16 implGetDateYear( double aDate ) { - Date aRefDate( 1,1,1900 ); - tools::Long nDays = static_cast<tools::Long>(aDate); - nDays -= 2; // standardize: 1.1.1900 => 0.0 + Date aRefDate(1899'12'30); + sal_Int32 nDays = static_cast<sal_Int32>(aDate); aRefDate.AddDays( nDays ); sal_Int16 nRet = aRefDate.GetYear(); return nRet; @@ -4820,40 +4537,34 @@ bool implDateSerial( sal_Int16 nYear, sal_Int16 nMonth, sal_Int16 nDay, } } - tools::Long nDiffDays = GetDayDiff( aCurDate ); - rdRet = static_cast<double>(nDiffDays); + rdRet = GetDayDiff(aCurDate); return true; } -double implTimeSerial( sal_Int16 nHours, sal_Int16 nMinutes, sal_Int16 nSeconds ) +double implTimeSerial(sal_Int16 nHours, sal_Int16 nMinutes, sal_Int16 nSeconds, + sal_Int32 nMilliSeconds) { - return - static_cast<double>( nHours * ::tools::Time::secondPerHour + - nMinutes * ::tools::Time::secondPerMinute + - nSeconds) - / - static_cast<double>( ::tools::Time::secondPerDay ); + return (nHours * ::tools::Time::milliSecPerHour + nMinutes * ::tools::Time::milliSecPerMinute + + nSeconds * ::tools::Time::milliSecPerSec + nMilliSeconds) + / static_cast<double>(::tools::Time::milliSecPerDay); } -bool implDateTimeSerial( sal_Int16 nYear, sal_Int16 nMonth, sal_Int16 nDay, - sal_Int16 nHour, sal_Int16 nMinute, sal_Int16 nSecond, - double& rdRet ) +bool implDateTimeSerial(sal_Int16 nYear, sal_Int16 nMonth, sal_Int16 nDay, sal_Int16 nHour, + sal_Int16 nMinute, sal_Int16 nSecond, sal_Int32 nMilliSecond, double& rdRet) { double dDate; if(!implDateSerial(nYear, nMonth, nDay, false/*bUseTwoDigitYear*/, SbDateCorrection::None, dDate)) return false; - rdRet += dDate + implTimeSerial(nHour, nMinute, nSecond); + rdRet += dDate + implTimeSerial(nHour, nMinute, nSecond, nMilliSecond); return true; } sal_Int16 implGetMinute( double dDate ) { - double nFrac = dDate - floor( dDate ); - nFrac *= 86400.0; - sal_Int32 nSeconds = static_cast<sal_Int32>(nFrac + 0.5); - sal_Int16 nTemp = static_cast<sal_Int16>(nSeconds % 3600); - sal_Int16 nMin = nTemp / 60; - return nMin; + double nFrac = (dDate - floor(dDate)) * ::tools::Time::milliSecPerDay; + sal_uInt64 nMilliSeconds = static_cast<sal_uInt64>(nFrac + 0.5); + return static_cast<sal_Int16>((nMilliSeconds / ::tools::Time::milliSecPerMinute) + % ::tools::Time::minutePerHour); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/basic/source/runtime/methods1.cxx b/basic/source/runtime/methods1.cxx index 117e84d73000..e1fd37e45018 100644 --- a/basic/source/runtime/methods1.cxx +++ b/basic/source/runtime/methods1.cxx @@ -24,7 +24,6 @@ #include <cstddef> -#include <stdlib.h> #include <rtl/math.hxx> #include <vcl/svapp.hxx> #include <vcl/mapmod.hxx> @@ -38,6 +37,7 @@ #include <tools/fract.hxx> #include <o3tl/temporary.hxx> #include <osl/file.hxx> +#include <osl/process.h> #include <sbobjmod.hxx> #include <basic/sbuno.hxx> @@ -61,6 +61,7 @@ #include <com/sun/star/lang/XMultiServiceFactory.hpp> #include <com/sun/star/i18n/LocaleCalendar2.hpp> #include <com/sun/star/sheet/XFunctionAccess.hpp> + #include <memory> using namespace comphelper; @@ -120,7 +121,7 @@ void SbRtl_CallByName(StarBASIC *, SbxArray & rPar, bool) return; } - // 2. parameter is ProcedureName + // 2. parameter is ProcName OUString aNameStr = rPar.Get(2)->GetOUString(); // 3. parameter is CallType @@ -277,15 +278,11 @@ void SbRtl_CDec(StarBASIC *, SbxArray & rPar, bool) void SbRtl_CDate(StarBASIC *, SbxArray & rPar, bool) // JSM { double nVal = 0.0; - if (rPar.Count() == 2) - { - SbxVariable* pSbxVariable = rPar.Get(1); - nVal = pSbxVariable->GetDate(); - } - else - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } + if (rPar.Count() != 2) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + SbxVariable* pSbxVariable = rPar.Get(1); + nVal = pSbxVariable->GetDate(); rPar.Get(0)->PutDate(nVal); } @@ -321,30 +318,22 @@ void SbRtl_CDbl(StarBASIC *, SbxArray & rPar, bool) // JSM void SbRtl_CInt(StarBASIC *, SbxArray & rPar, bool) // JSM { sal_Int16 nVal = 0; - if (rPar.Count() == 2) - { - SbxVariable* pSbxVariable = rPar.Get(1); - nVal = pSbxVariable->GetInteger(); - } - else - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } + if (rPar.Count() != 2) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + SbxVariable* pSbxVariable = rPar.Get(1); + nVal = pSbxVariable->GetInteger(); rPar.Get(0)->PutInteger(nVal); } void SbRtl_CLng(StarBASIC *, SbxArray & rPar, bool) // JSM { sal_Int32 nVal = 0; - if (rPar.Count() == 2) - { - SbxVariable* pSbxVariable = rPar.Get(1); - nVal = pSbxVariable->GetLong(); - } - else - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } + if (rPar.Count() != 2) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + SbxVariable* pSbxVariable = rPar.Get(1); + nVal = pSbxVariable->GetLong(); rPar.Get(0)->PutLong(nVal); } @@ -380,16 +369,11 @@ void SbRtl_CSng(StarBASIC *, SbxArray & rPar, bool) // JSM void SbRtl_CStr(StarBASIC *, SbxArray & rPar, bool) // JSM { - OUString aString; - if (rPar.Count() == 2) - { - SbxVariable* pSbxVariable = rPar.Get(1); - aString = pSbxVariable->GetOUString(); - } - else - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } + if (rPar.Count() != 2) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + SbxVariable* pSbxVariable = rPar.Get(1); + OUString aString = pSbxVariable->GetOUString(); rPar.Get(0)->PutString(aString); } @@ -410,112 +394,86 @@ void SbRtl_CVar(StarBASIC *, SbxArray & rPar, bool) // JSM void SbRtl_CVErr(StarBASIC *, SbxArray & rPar, bool) { - sal_Int16 nErrCode = 0; - if (rPar.Count() == 2) - { - SbxVariable* pSbxVariable = rPar.Get(1); - nErrCode = pSbxVariable->GetInteger(); - } - else - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } + if (rPar.Count() != 2) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + SbxVariable* pSbxVariable = rPar.Get(1); + sal_Int16 nErrCode = pSbxVariable->GetInteger(); rPar.Get(0)->PutErr(nErrCode); } void SbRtl_Iif(StarBASIC *, SbxArray & rPar, bool) // JSM { - if (rPar.Count() == 4) + if (rPar.Count() != 4) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + if (rPar.Get(1)->GetBool()) { - if (rPar.Get(1)->GetBool()) - { - *rPar.Get(0) = *rPar.Get(2); - } - else - { - *rPar.Get(0) = *rPar.Get(3); - } + *rPar.Get(0) = *rPar.Get(2); } else { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + *rPar.Get(0) = *rPar.Get(3); } + } void SbRtl_GetSystemType(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() != 1) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } - else - { + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + // Removed for SRC595 - rPar.Get(0)->PutInteger(-1); - } + rPar.Get(0)->PutInteger(-1); } void SbRtl_GetGUIType(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() != 1) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } - else - { + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + // 17.7.2000 Make simple solution for testtool / fat office #if defined(_WIN32) - rPar.Get(0)->PutInteger(1); + rPar.Get(0)->PutInteger(1); #elif defined(UNX) - rPar.Get(0)->PutInteger(4); + rPar.Get(0)->PutInteger(4); #else - rPar.Get(0)->PutInteger(-1); + rPar.Get(0)->PutInteger(-1); #endif - } } void SbRtl_Red(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() != 2) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } - else - { - sal_Int32 nRGB = rPar.Get(1)->GetLong(); - nRGB &= 0x00FF0000; - nRGB >>= 16; - rPar.Get(0)->PutInteger(static_cast<sal_Int16>(nRGB)); - } + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + sal_Int32 nRGB = rPar.Get(1)->GetLong(); + nRGB &= 0x00FF0000; + nRGB >>= 16; + rPar.Get(0)->PutInteger(static_cast<sal_Int16>(nRGB)); + } void SbRtl_Green(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() != 2) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } - else - { - sal_Int32 nRGB = rPar.Get(1)->GetLong(); - nRGB &= 0x0000FF00; - nRGB >>= 8; - rPar.Get(0)->PutInteger(static_cast<sal_Int16>(nRGB)); - } + + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + sal_Int32 nRGB = rPar.Get(1)->GetLong(); + nRGB &= 0x0000FF00; + nRGB >>= 8; + rPar.Get(0)->PutInteger(static_cast<sal_Int16>(nRGB)); } void SbRtl_Blue(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() != 2) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } - else - { - sal_Int32 nRGB = rPar.Get(1)->GetLong(); - nRGB &= 0x000000FF; - rPar.Get(0)->PutInteger(static_cast<sal_Int16>(nRGB)); - } + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + sal_Int32 nRGB = rPar.Get(1)->GetLong(); + nRGB &= 0x000000FF; + rPar.Get(0)->PutInteger(static_cast<sal_Int16>(nRGB)); } @@ -525,7 +483,7 @@ void SbRtl_Switch(StarBASIC *, SbxArray & rPar, bool) if( !(nCount & 0x0001 )) { // number of arguments must be odd - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); } sal_uInt32 nCurExpr = 1; while( nCurExpr < (nCount-1) ) @@ -545,10 +503,8 @@ void SbRtl_Switch(StarBASIC *, SbxArray & rPar, bool) void Wait_Impl( bool bDurationBased, SbxArray& rPar ) { if (rPar.Count() != 2) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; - } + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + tools::Long nWait = 0; if ( bDurationBased ) { @@ -561,11 +517,9 @@ void Wait_Impl( bool bDurationBased, SbxArray& rPar ) { nWait = rPar.Get(1)->GetLong(); } + if( nWait < 0 ) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; - } + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); Timer aTimer("basic Wait_Impl"); aTimer.SetTimeout( nWait ); @@ -602,14 +556,10 @@ void SbRtl_DoEvents(StarBASIC *, SbxArray & rPar, bool) void SbRtl_GetGUIVersion(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() != 1) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } - else - { - // Removed for SRC595 - rPar.Get(0)->PutLong(-1); - } + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + // Removed for SRC595 + rPar.Get(0)->PutLong(-1); } void SbRtl_Choose(StarBASIC *, SbxArray & rPar, bool) @@ -634,13 +584,10 @@ void SbRtl_Trim(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() < 2) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } - else - { - OUString aStr(comphelper::string::strip(rPar.Get(1)->GetOUString(), ' ')); - rPar.Get(0)->PutString(aStr); + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); } + OUString aStr(comphelper::string::strip(rPar.Get(1)->GetOUString(), ' ')); + rPar.Get(0)->PutString(aStr); } void SbRtl_GetSolarVersion(StarBASIC *, SbxArray & rPar, bool) @@ -808,11 +755,9 @@ void SbRtl_DimArray(StarBASIC *, SbxArray & rPar, bool) // 1st parameter = the object's name as string void SbRtl_FindObject(StarBASIC *, SbxArray & rPar, bool) { - if (rPar.Count() < 2) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; - } + if (rPar.Count() != 2) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + OUString aNameStr = rPar.Get(1)->GetOUString(); @@ -831,11 +776,9 @@ void SbRtl_FindObject(StarBASIC *, SbxArray & rPar, bool) // 2nd parameter = the property's name as string void SbRtl_FindPropertyObject(StarBASIC *, SbxArray & rPar, bool) { - if (rPar.Count() < 3) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; - } + if (rPar.Count() != 3) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + SbxBase* pObjVar = rPar.Get(1)->GetObject(); SbxObject* pObj = nullptr; @@ -936,20 +879,20 @@ static bool lcl_WriteSbxVariable( const SbxVariable& rVar, SvStream* pStrm, case SbxSTRING: case SbxLPSTR: { - const OUString& rStr = rVar.GetOUString(); + const OUString aStr = rVar.GetOUString(); if( !bBinary || bIsArray ) { if( bIsVariant ) { pStrm->WriteUInt16( SbxSTRING ); } - pStrm->WriteUniOrByteString( rStr, osl_getThreadTextEncoding() ); + pStrm->WriteUniOrByteString( aStr, osl_getThreadTextEncoding() ); } else { // without any length information! without end-identifier! // What does that mean for Unicode?! Choosing conversion to ByteString... - OString aByteStr(OUStringToOString(rStr, osl_getThreadTextEncoding())); + OString aByteStr(OUStringToOString(aStr, osl_getThreadTextEncoding())); pStrm->WriteOString( aByteStr ); } } @@ -1107,10 +1050,8 @@ static bool lcl_WriteReadSbxArray( SbxDimArray& rArr, SvStream* pStrm, static void PutGet( SbxArray& rPar, bool bPut ) { if (rPar.Count() != 4) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; - } + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + sal_Int16 nFileNo = rPar.Get(1)->GetInteger(); SbxVariable* pVar2 = rPar.Get(2); SbxDataType eType2 = pVar2->GetType(); @@ -1126,10 +1067,7 @@ static void PutGet( SbxArray& rPar, bool bPut ) SbiStream* pSbStrm = pIO->GetStream( nFileNo ); if ( !pSbStrm || !(pSbStrm->GetMode() & (SbiStreamFlags::Binary | SbiStreamFlags::Random)) ) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_CHANNEL ); - return; - } + return StarBASIC::Error( ERRCODE_BASIC_BAD_CHANNEL ); SvStream* pStrm = pSbStrm->GetStrm(); bool bRandom = pSbStrm->IsRandom(); @@ -1192,19 +1130,10 @@ void SbRtl_Get(StarBASIC *, SbxArray & rPar, bool) void SbRtl_Environ(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() != 2) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; - } + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + OUString aResult; - // should be ANSI but that's not possible under Win16 in the DLL - OString aByteStr(OUStringToOString(rPar.Get(1)->GetOUString(), - osl_getThreadTextEncoding())); - const char* pEnvStr = getenv(aByteStr.getStr()); - if ( pEnvStr ) - { - aResult = OUString(pEnvStr, strlen(pEnvStr), osl_getThreadTextEncoding()); - } + osl_getEnvironment(rPar.Get(1)->GetOUString().pData, &aResult.pData); rPar.Get(0)->PutString(aResult); } @@ -1241,20 +1170,15 @@ static double GetDialogZoomFactor( bool bX, tools::Long nValue ) void SbRtl_GetDialogZoomFactorX(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() != 2) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; - } + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); rPar.Get(0)->PutDouble(GetDialogZoomFactor(true, rPar.Get(1)->GetLong())); } void SbRtl_GetDialogZoomFactorY(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() != 2) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; - } + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + rPar.Get(0)->PutDouble(GetDialogZoomFactor(false, rPar.Get(1)->GetLong())); } @@ -1271,109 +1195,94 @@ void SbRtl_EnableReschedule(StarBASIC *, SbxArray & rPar, bool) void SbRtl_GetSystemTicks(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() != 1) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; - } + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + rPar.Get(0)->PutLong(tools::Time::GetSystemTicks()); } void SbRtl_GetPathSeparator(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() != 1) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; - } + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + rPar.Get(0)->PutString(OUString(SAL_PATHDELIMITER)); } void SbRtl_ResolvePath(StarBASIC *, SbxArray & rPar, bool) { - if (rPar.Count() == 2) - { - OUString aStr = rPar.Get(1)->GetOUString(); - rPar.Get(0)->PutString(aStr); - } - else - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } + if (rPar.Count() != 2) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + OUString aStr = rPar.Get(1)->GetOUString(); + rPar.Get(0)->PutString(aStr); } void SbRtl_TypeLen(StarBASIC *, SbxArray & rPar, bool) { if (rPar.Count() != 2) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + SbxDataType eType = rPar.Get(1)->GetType(); + sal_Int16 nLen = 0; + switch( eType ) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - } - else - { - SbxDataType eType = rPar.Get(1)->GetType(); - sal_Int16 nLen = 0; - switch( eType ) - { - case SbxEMPTY: - case SbxNULL: - case SbxVECTOR: - case SbxARRAY: - case SbxBYREF: - case SbxVOID: - case SbxHRESULT: - case SbxPOINTER: - case SbxDIMARRAY: - case SbxCARRAY: - case SbxUSERDEF: - nLen = 0; - break; + case SbxEMPTY: + case SbxNULL: + case SbxVECTOR: + case SbxARRAY: + case SbxBYREF: + case SbxVOID: + case SbxHRESULT: + case SbxPOINTER: + case SbxDIMARRAY: + case SbxCARRAY: + case SbxUSERDEF: + case SbxOBJECT: + case SbxVARIANT: + case SbxDATAOBJECT: + nLen = 0; + break; - case SbxINTEGER: - case SbxERROR: - case SbxUSHORT: - case SbxINT: - case SbxUINT: - nLen = 2; - break; + case SbxINTEGER: + case SbxERROR: + case SbxUSHORT: + case SbxINT: + case SbxUINT: + nLen = 2; + break; - case SbxLONG: - case SbxSINGLE: - case SbxULONG: - nLen = 4; - break; + case SbxLONG: + case SbxSINGLE: + case SbxULONG: + nLen = 4; + break; - case SbxDOUBLE: - case SbxCURRENCY: - case SbxDATE: - case SbxSALINT64: - case SbxSALUINT64: - nLen = 8; - break; + case SbxDOUBLE: + case SbxCURRENCY: + case SbxDATE: + case SbxSALINT64: + case SbxSALUINT64: + nLen = 8; + break; - case SbxOBJECT: - case SbxVARIANT: - case SbxDATAOBJECT: - nLen = 0; + case SbxCHAR: + case SbxBYTE: + case SbxBOOL: + nLen = 1; break; - case SbxCHAR: - case SbxBYTE: - case SbxBOOL: - nLen = 1; - break; - - case SbxLPSTR: - case SbxLPWSTR: - case SbxCoreSTRING: - case SbxSTRING: - nLen = static_cast<sal_Int16>(rPar.Get(1)->GetOUString().getLength()); - break; + case SbxLPSTR: + case SbxLPWSTR: + case SbxCoreSTRING: + case SbxSTRING: + nLen = static_cast<sal_Int16>(rPar.Get(1)->GetOUString().getLength()); + break; - default: - nLen = 0; - break; - } - rPar.Get(0)->PutInteger(nLen); + default: + nLen = 0; + break; } + rPar.Get(0)->PutInteger(nLen); } @@ -1454,44 +1363,37 @@ void SbRtl_GlobalScope(StarBASIC * pBasic, SbxArray & rPar, bool) // Helper functions to convert Url from/to system paths void SbRtl_ConvertToUrl(StarBASIC *, SbxArray & rPar, bool) { - if (rPar.Count() == 2) + if (rPar.Count() != 2) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + OUString aStr = rPar.Get(1)->GetOUString(); + INetURLObject aURLObj( aStr, INetProtocol::File ); + OUString aFileURL = aURLObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ); + if( aFileURL.isEmpty() ) { - OUString aStr = rPar.Get(1)->GetOUString(); - INetURLObject aURLObj( aStr, INetProtocol::File ); - OUString aFileURL = aURLObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ); - if( aFileURL.isEmpty() ) - { - osl::File::getFileURLFromSystemPath(aStr, aFileURL); - } - if( aFileURL.isEmpty() ) - { - aFileURL = aStr; - } - rPar.Get(0)->PutString(aFileURL); + osl::File::getFileURLFromSystemPath(aStr, aFileURL); } - else + if( aFileURL.isEmpty() ) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + aFileURL = aStr; } + rPar.Get(0)->PutString(aFileURL); + } void SbRtl_ConvertFromUrl(StarBASIC *, SbxArray & rPar, bool) { - if (rPar.Count() == 2) - { - OUString aStr = rPar.Get(1)->GetOUString(); - OUString aSysPath; - ::osl::File::getSystemPathFromFileURL( aStr, aSysPath ); - if( aSysPath.isEmpty() ) - { - aSysPath = aStr; - } - rPar.Get(0)->PutString(aSysPath); - } - else + if (rPar.Count() != 2) + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + + OUString aStr = rPar.Get(1)->GetOUString(); + OUString aSysPath; + ::osl::File::getSystemPathFromFileURL( aStr, aSysPath ); + if( aSysPath.isEmpty() ) { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + aSysPath = aStr; } + rPar.Get(0)->PutString(aSysPath); } @@ -1505,47 +1407,40 @@ void SbRtl_Join(StarBASIC *, SbxArray & rPar, bool) { sal_uInt32 nParCount = rPar.Count(); if ( nParCount != 3 && nParCount != 2 ) - { - StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); - return; - } + return StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); + SbxBase* pParObj = rPar.Get(1)->GetObject(); SbxDimArray* pArr = dynamic_cast<SbxDimArray*>( pParObj ); - if( pArr ) + if( !pArr ) + return StarBASIC::Error( ERRCODE_BASIC_MUST_HAVE_DIMS ); + + if (pArr->GetDims() != 1) + return StarBASIC::Error( ERRCODE_BASIC_WRONG_DIMS ); // Syntax Error?! + + OUString aDelim; + if( nParCount == 3 ) { - if (pArr->GetDims() != 1) - { - StarBASIC::Error( ERRCODE_BASIC_WRONG_DIMS ); // Syntax Error?! - return; - } - OUString aDelim; - if( nParCount == 3 ) - { - aDelim = rPar.Get(2)->GetOUString(); - } - else - { - aDelim = " "; - } - OUStringBuffer aRetStr(32); - sal_Int32 nLower, nUpper; - pArr->GetDim(1, nLower, nUpper); - sal_Int32 aIdx[1]; - for (aIdx[0] = nLower; aIdx[0] <= nUpper; ++aIdx[0]) - { - OUString aStr = pArr->Get(aIdx)->GetOUString(); - aRetStr.append(aStr); - if (aIdx[0] != nUpper) - { - aRetStr.append(aDelim); - } - } - rPar.Get(0)->PutString(aRetStr.makeStringAndClear()); + aDelim = rPar.Get(2)->GetOUString(); } else { - StarBASIC::Error( ERRCODE_BASIC_MUST_HAVE_DIMS ); + aDelim = " "; } + OUStringBuffer aRetStr(32); + sal_Int32 nLower, nUpper; + pArr->GetDim(1, nLower, nUpper); + sal_Int32 aIdx[1]; + for (aIdx[0] = nLower; aIdx[0] <= nUpper; ++aIdx[0]) + { + OUString aStr = pArr->Get(aIdx)->GetOUString(); + aRetStr.append(aStr); + if (aIdx[0] != nUpper) + { + aRetStr.append(aDelim); + } + } + rPar.Get(0)->PutString(aRetStr.makeStringAndClear()); + } @@ -1744,7 +1639,7 @@ void SbRtl_WeekdayName(StarBASIC *, SbxArray & rPar, bool) void SbRtl_Weekday(StarBASIC *, SbxArray & rPar, bool) { sal_uInt32 nParCount = rPar.Count(); - if ( nParCount < 2 ) + if ( nParCount < 2 || nParCount > 3 ) { StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT ); } @@ -1805,13 +1700,13 @@ static IntervalInfo const * getIntervalInfo( const OUString& rStringCode ) { INTERVAL_N, "n", 1.0 / 1440.0, true }, // Minute { INTERVAL_S, "s", 1.0 / 86400.0, true } // Second }; - for( std::size_t i = 0; i != SAL_N_ELEMENTS(aIntervalTable); ++i ) - { - if( rStringCode.equalsIgnoreAsciiCaseAscii( - aIntervalTable[i].mStringCode ) ) - { - return &aIntervalTable[i]; - } + auto const pred = [&rStringCode](const IntervalInfo &aInterval) { + return rStringCode.equalsIgnoreAsciiCaseAscii(aInterval.mStringCode); + }; + + auto intervalIter = std::find_if(std::begin(aIntervalTable), std::end(aIntervalTable), pred); + if(intervalIter != std::end(aIntervalTable)) { + return intervalIter; } return nullptr; } @@ -2416,7 +2311,7 @@ static void CallFunctionAccessFunction( const Sequence< Any >& aArgs, const OUSt Reference< XMultiServiceFactory > xFactory( getProcessServiceFactory() ); if( xFactory.is() ) { - xFunc.set( xFactory->createInstance("com.sun.star.sheet.FunctionAccess"), UNO_QUERY_THROW); + xFunc.set( xFactory->createInstance(u"com.sun.star.sheet.FunctionAccess"_ustr), UNO_QUERY_THROW); } } Any aRet = xFunc->callFunction( sFuncName, aArgs ); @@ -2444,13 +2339,13 @@ void SbRtl_SYD(StarBASIC *, SbxArray & rPar, bool) Sequence< Any > aParams { - makeAny(rPar.Get(1)->GetDouble()), - makeAny(rPar.Get(2)->GetDouble()), - makeAny(rPar.Get(3)->GetDouble()), - makeAny(rPar.Get(4)->GetDouble()) + Any(rPar.Get(1)->GetDouble()), + Any(rPar.Get(2)->GetDouble()), + Any(rPar.Get(3)->GetDouble()), + Any(rPar.Get(4)->GetDouble()) }; - CallFunctionAccessFunction(aParams, "SYD", rPar.Get(0)); + CallFunctionAccessFunction(aParams, u"SYD"_ustr, rPar.Get(0)); } void SbRtl_SLN(StarBASIC *, SbxArray & rPar, bool) @@ -2467,12 +2362,12 @@ void SbRtl_SLN(StarBASIC *, SbxArray & rPar, bool) Sequence< Any > aParams { - makeAny(rPar.Get(1)->GetDouble()), - makeAny(rPar.Get(2)->GetDouble()), - makeAny(rPar.Get(3)->GetDouble()) + Any(rPar.Get(1)->GetDouble()), + Any(rPar.Get(2)->GetDouble()), + Any(rPar.Get(3)->GetDouble()) }; - CallFunctionAccessFunction(aParams, "SLN", rPar.Get(0)); + CallFunctionAccessFunction(aParams, u"SLN"_ustr, rPar.Get(0)); } void SbRtl_Pmt(StarBASIC *, SbxArray & rPar, bool) @@ -2509,14 +2404,14 @@ void SbRtl_Pmt(StarBASIC *, SbxArray & rPar, bool) Sequence< Any > aParams { - makeAny(rate), - makeAny(nper), - makeAny(pmt), - makeAny(fv), - makeAny(type) + Any(rate), + Any(nper), + Any(pmt), + Any(fv), + Any(type) }; - CallFunctionAccessFunction(aParams, "Pmt", rPar.Get(0)); + CallFunctionAccessFunction(aParams, u"Pmt"_ustr, rPar.Get(0)); } void SbRtl_PPmt(StarBASIC *, SbxArray & rPar, bool) @@ -2554,15 +2449,15 @@ void SbRtl_PPmt(StarBASIC *, SbxArray & rPar, bool) Sequence< Any > aParams { - makeAny(rate), - makeAny(per), - makeAny(nper), - makeAny(pv), - makeAny(fv), - makeAny(type) + Any(rate), + Any(per), + Any(nper), + Any(pv), + Any(fv), + Any(type) }; - CallFunctionAccessFunction(aParams, "PPmt", rPar.Get(0)); + CallFunctionAccessFunction(aParams, u"PPmt"_ustr, rPar.Get(0)); } void SbRtl_PV(StarBASIC *, SbxArray & rPar, bool) @@ -2599,14 +2494,14 @@ void SbRtl_PV(StarBASIC *, SbxArray & rPar, bool) Sequence< Any > aParams { - makeAny(rate), - makeAny(nper), - makeAny(pmt), - makeAny(fv), - makeAny(type) + Any(rate), + Any(nper), + Any(pmt), + Any(fv), + Any(type) }; - CallFunctionAccessFunction(aParams, "PV", rPar.Get(0)); + CallFunctionAccessFunction(aParams, u"PV"_ustr, rPar.Get(0)); } void SbRtl_NPV(StarBASIC *, SbxArray & rPar, bool) @@ -2629,11 +2524,11 @@ void SbRtl_NPV(StarBASIC *, SbxArray & rPar, bool) Sequence< Any > aParams { - makeAny(rPar.Get(1)->GetDouble()), + Any(rPar.Get(1)->GetDouble()), aValues }; - CallFunctionAccessFunction(aParams, "NPV", rPar.Get(0)); + CallFunctionAccessFunction(aParams, u"NPV"_ustr, rPar.Get(0)); } void SbRtl_NPer(StarBASIC *, SbxArray & rPar, bool) @@ -2670,14 +2565,14 @@ void SbRtl_NPer(StarBASIC *, SbxArray & rPar, bool) Sequence< Any > aParams { - makeAny(rate), - makeAny(pmt), - makeAny(pv), - makeAny(fv), - makeAny(type) + Any(rate), + Any(pmt), + Any(pv), + Any(fv), + Any(type) }; - CallFunctionAccessFunction(aParams, "NPer", rPar.Get(0)); + CallFunctionAccessFunction(aParams, u"NPer"_ustr, rPar.Get(0)); } void SbRtl_MIRR(StarBASIC *, SbxArray & rPar, bool) @@ -2703,11 +2598,11 @@ void SbRtl_MIRR(StarBASIC *, SbxArray & rPar, bool) Sequence< Any > aParams { aValues, - makeAny(rPar.Get(2)->GetDouble()), - makeAny(rPar.Get(3)->GetDouble()) + Any(rPar.Get(2)->GetDouble()), + Any(rPar.Get(3)->GetDouble()) }; - CallFunctionAccessFunction(aParams, "MIRR", rPar.Get(0)); + CallFunctionAccessFunction(aParams, u"MIRR"_ustr, rPar.Get(0)); } void SbRtl_IRR(StarBASIC *, SbxArray & rPar, bool) @@ -2740,10 +2635,10 @@ void SbRtl_IRR(StarBASIC *, SbxArray & rPar, bool) Sequence< Any > aParams { aValues, - makeAny(guess) + Any(guess) }; - CallFunctionAccessFunction(aParams, "IRR", rPar.Get(0)); + CallFunctionAccessFunction(aParams, u"IRR"_ustr, rPar.Get(0)); } void SbRtl_IPmt(StarBASIC *, SbxArray & rPar, bool) @@ -2781,15 +2676,15 @@ void SbRtl_IPmt(StarBASIC *, SbxArray & rPar, bool) Sequence< Any > aParams { - makeAny(rate), - makeAny(per), - makeAny(nper), - makeAny(pv), - makeAny(fv), - makeAny(type) + Any(rate), + Any(per), + Any(nper), + Any(pv), + Any(fv), + Any(type) }; - CallFunctionAccessFunction(aParams, "IPmt", rPar.Get(0)); + CallFunctionAccessFunction(aParams, u"IPmt"_ustr, rPar.Get(0)); } void SbRtl_FV(StarBASIC *, SbxArray & rPar, bool) @@ -2826,14 +2721,14 @@ void SbRtl_FV(StarBASIC *, SbxArray & rPar, bool) Sequence< Any > aParams { - makeAny(rate), - makeAny(nper), - makeAny(pmt), - makeAny(pv), - makeAny(type) + Any(rate), + Any(nper), + Any(pmt), + Any(pv), + Any(type) }; - CallFunctionAccessFunction(aParams, "FV", rPar.Get(0)); + CallFunctionAccessFunction(aParams, u"FV"_ustr, rPar.Get(0)); } void SbRtl_DDB(StarBASIC *, SbxArray & rPar, bool) @@ -2864,14 +2759,14 @@ void SbRtl_DDB(StarBASIC *, SbxArray & rPar, bool) Sequence< Any > aParams { - makeAny(cost), - makeAny(salvage), - makeAny(life), - makeAny(period), - makeAny(factor) + Any(cost), + Any(salvage), + Any(life), + Any(period), + Any(factor) }; - CallFunctionAccessFunction(aParams, "DDB", rPar.Get(0)); + CallFunctionAccessFunction(aParams, u"DDB"_ustr, rPar.Get(0)); } void SbRtl_Rate(StarBASIC *, SbxArray & rPar, bool) @@ -2921,15 +2816,15 @@ void SbRtl_Rate(StarBASIC *, SbxArray & rPar, bool) Sequence< Any > aParams { - makeAny(nper), - makeAny(pmt), - makeAny(pv), - makeAny(fv), - makeAny(type), - makeAny(guess) + Any(nper), + Any(pmt), + Any(pv), + Any(fv), + Any(type), + Any(guess) }; - CallFunctionAccessFunction(aParams, "Rate", rPar.Get(0)); + CallFunctionAccessFunction(aParams, u"Rate"_ustr, rPar.Get(0)); } void SbRtl_StrReverse(StarBASIC *, SbxArray & rPar, bool) @@ -3024,9 +2919,8 @@ void SbRtl_Me(StarBASIC *, SbxArray & rPar, bool) sal_Int16 implGetWeekDay( double aDate, bool bFirstDayParam, sal_Int16 nFirstDay ) { - Date aRefDate( 1,1,1900 ); + Date aRefDate(1899'12'30); sal_Int32 nDays = static_cast<sal_Int32>(aDate); - nDays -= 2; // normalize: 1.1.1900 => 0 aRefDate.AddDays( nDays); DayOfWeek aDay = aRefDate.GetDayOfWeek(); sal_Int16 nDay; diff --git a/basic/source/runtime/props.cxx b/basic/source/runtime/props.cxx index f3d84a0127b5..3eccc378efee 100644 --- a/basic/source/runtime/props.cxx +++ b/basic/source/runtime/props.cxx @@ -21,7 +21,6 @@ #include <runtime.hxx> #include <rtlproto.hxx> #include <errobject.hxx> -#include <basegfx/numeric/ftools.hxx> // Properties and methods lay the return value down at Get (bWrite = sal_False) @@ -49,8 +48,6 @@ void SbRtl_Err(StarBASIC *, SbxArray & rPar, bool bWrite) } } -void SbRtl_False(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutBool(false); } - void SbRtl_Empty(StarBASIC *, SbxArray &, bool) {} void SbRtl_Nothing(StarBASIC *, SbxArray & rPar, bool) @@ -67,106 +64,4 @@ void SbRtl_Null(StarBASIC *, SbxArray & rPar, bool) void SbRtl_PI(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutDouble(M_PI); } -void SbRtl_True(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutBool(true); } - -void SbRtl_ATTR_NORMAL(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(0); } -void SbRtl_ATTR_READONLY(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(1); } -void SbRtl_ATTR_HIDDEN(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(2); } -void SbRtl_ATTR_SYSTEM(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(4); } -void SbRtl_ATTR_VOLUME(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(8); } -void SbRtl_ATTR_DIRECTORY(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(16); } -void SbRtl_ATTR_ARCHIVE(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(32); } - -void SbRtl_V_EMPTY(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(0); } -void SbRtl_V_NULL(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(1); } -void SbRtl_V_INTEGER(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(2); } -void SbRtl_V_LONG(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(3); } -void SbRtl_V_SINGLE(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(4); } -void SbRtl_V_DOUBLE(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(5); } -void SbRtl_V_CURRENCY(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(6); } -void SbRtl_V_DATE(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(7); } -void SbRtl_V_STRING(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(8); } - -void SbRtl_MB_OK(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(0); } -void SbRtl_MB_OKCANCEL(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(1); } -void SbRtl_MB_ABORTRETRYIGNORE(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(2); } -void SbRtl_MB_YESNOCANCEL(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(3); } -void SbRtl_MB_YESNO(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(4); } -void SbRtl_MB_RETRYCANCEL(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(5); } -void SbRtl_MB_ICONSTOP(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(16); } -void SbRtl_MB_ICONQUESTION(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(32); } -void SbRtl_MB_ICONEXCLAMATION(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(48); } -void SbRtl_MB_ICONINFORMATION(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(64); } -void SbRtl_MB_DEFBUTTON1(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(0); } -void SbRtl_MB_DEFBUTTON2(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(256); } -void SbRtl_MB_DEFBUTTON3(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(512); } -void SbRtl_MB_APPLMODAL(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(0); } -void SbRtl_MB_SYSTEMMODAL(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(4096); } - -void SbRtl_IDOK(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(1); } - -void SbRtl_IDCANCEL(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(2); } -void SbRtl_IDABORT(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(3); } -void SbRtl_IDRETRY(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(4); } -void SbRtl_IDYES(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(6); } -void SbRtl_IDNO(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(7); } - -void SbRtl_CF_TEXT(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(1); } -void SbRtl_CF_BITMAP(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(2); } -void SbRtl_CF_METAFILEPICT(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(3); } - -void SbRtl_TYP_AUTHORFLD(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(7); } -void SbRtl_TYP_CHAPTERFLD(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(4); } -void SbRtl_TYP_CONDTXTFLD(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(27); } -void SbRtl_TYP_DATEFLD(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(0); } -void SbRtl_TYP_DBFLD(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(19); } -void SbRtl_TYP_DBNAMEFLD(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(3); } -void SbRtl_TYP_DBNEXTSETFLD(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(24); } -void SbRtl_TYP_DBNUMSETFLD(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(25); } -void SbRtl_TYP_DBSETNUMBERFLD(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(26); } -void SbRtl_TYP_DDEFLD(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(14); } -void SbRtl_TYP_DOCINFOFLD(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(18); } -void SbRtl_TYP_DOCSTATFLD(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(6); } -void SbRtl_TYP_EXTUSERFLD(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(30); } -void SbRtl_TYP_FILENAMEFLD(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(2); } -void SbRtl_TYP_FIXDATEFLD(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(31); } -void SbRtl_TYP_FIXTIMEFLD(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(32); } -void SbRtl_TYP_FORMELFLD(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(10); } -void SbRtl_TYP_GETFLD(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(9); } -void SbRtl_TYP_GETREFFLD(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(13); } -void SbRtl_TYP_HIDDENPARAFLD(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(17); } -void SbRtl_TYP_HIDDENTXTFLD(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(11); } -void SbRtl_TYP_INPUTFLD(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(16); } -void SbRtl_TYP_MACROFLD(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(15); } -void SbRtl_TYP_NEXTPAGEFLD(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(28); } -void SbRtl_TYP_PAGENUMBERFLD(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(5); } -void SbRtl_TYP_POSTITFLD(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(21); } -void SbRtl_TYP_PREVPAGEFLD(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(29); } -void SbRtl_TYP_SEQFLD(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(23); } -void SbRtl_TYP_SETFLD(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(8); } -void SbRtl_TYP_SETINPFLD(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(33); } -void SbRtl_TYP_SETREFFLD(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(12); } -void SbRtl_TYP_TEMPLNAMEFLD(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(22); } -void SbRtl_TYP_TIMEFLD(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(1); } -void SbRtl_TYP_USERFLD(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(20); } -void SbRtl_TYP_USRINPFLD(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(34); } -void SbRtl_TYP_SETREFPAGEFLD(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(35); } -void SbRtl_TYP_GETREFPAGEFLD(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(36); } -void SbRtl_TYP_INTERNETFLD(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(37); } - -void SbRtl_SET_ON(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(1); } -void SbRtl_SET_OFF(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(0); } -void SbRtl_TOGGLE(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(2); } - -void SbRtl_FRAMEANCHORPAGE(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(1); } -void SbRtl_FRAMEANCHORPARA(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(14); } -void SbRtl_FRAMEANCHORCHAR(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(15); } - -void SbRtl_CLEAR_ALLTABS(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(2); } -void SbRtl_CLEAR_TAB(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(1); } -void SbRtl_SET_TAB(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(0); } - -void SbRtl_TYP_JUMPEDITFLD(StarBASIC*, SbxArray& rPar, bool) { rPar.Get(0)->PutInteger(38); } - - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/basic/source/runtime/runtime.cxx b/basic/source/runtime/runtime.cxx index bad307f27dd6..92ebafec70da 100644 --- a/basic/source/runtime/runtime.cxx +++ b/basic/source/runtime/runtime.cxx @@ -36,8 +36,9 @@ #include <sal/log.hxx> #include <tools/wldcrd.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> +#include <utility> #include <vcl/svapp.hxx> #include <vcl/settings.hxx> @@ -48,9 +49,7 @@ #include <svl/numformat.hxx> #include <svl/zforlist.hxx> -#include <i18nutil/searchopt.hxx> -#include <unotools/syslocale.hxx> -#include <unotools/textsearch.hxx> +#include <unicode/regex.h> #include <basic/sbuno.hxx> @@ -75,11 +74,12 @@ using com::sun::star::uno::Reference; using namespace com::sun::star::uno; using namespace com::sun::star::container; using namespace com::sun::star::lang; -using namespace com::sun::star::beans; using namespace com::sun::star::script; using namespace ::com::sun::star; +#if HAVE_FEATURE_SCRIPTING + static void lcl_clearImpl( SbxVariableRef const & refVar, SbxDataType const & eType ); static void lcl_eraseImpl( SbxVariableRef const & refVar, bool bVBAEnabled ); @@ -89,17 +89,16 @@ class ScopedWritableGuard { public: ScopedWritableGuard(const SbxVariableRef& rVar, bool bMakeWritable) - : m_rVar(rVar) - , m_bReset(bMakeWritable && !rVar->CanWrite()) + : m_rVar(bMakeWritable && !rVar->CanWrite() ? rVar : SbxVariableRef()) { - if (m_bReset) + if (m_rVar) { m_rVar->SetFlag(SbxFlagBits::Write); } } ~ScopedWritableGuard() { - if (m_bReset) + if (m_rVar) { m_rVar->ResetFlag(SbxFlagBits::Write); } @@ -107,17 +106,13 @@ public: private: SbxVariableRef m_rVar; - bool m_bReset; }; } bool SbiRuntime::isVBAEnabled() { - bool bResult = false; SbiInstance* pInst = GetSbData()->pInst; - if ( pInst && GetSbData()->pInst->pRun ) - bResult = pInst->pRun->bVBAEnabled; - return bResult; + return pInst && pInst->pRun && pInst->pRun->bVBAEnabled; } void StarBASIC::SetVBAEnabled( bool bEnabled ) @@ -130,21 +125,15 @@ void StarBASIC::SetVBAEnabled( bool bEnabled ) bool StarBASIC::isVBAEnabled() const { - if ( bDocBasic ) - { - if( SbiRuntime::isVBAEnabled() ) - return true; - return bVBAEnabled; - } - return false; + return bDocBasic && (bVBAEnabled || SbiRuntime::isVBAEnabled()); } struct SbiArgv { // Argv stack: SbxArrayRef refArgv; // Argv short nArgc; // Argc - SbiArgv(SbxArrayRef const & refArgv_, short nArgc_) : - refArgv(refArgv_), + SbiArgv(SbxArrayRef refArgv_, short nArgc_) : + refArgv(std::move(refArgv_)), nArgc(nArgc_) {} }; @@ -289,7 +278,7 @@ const SbiRuntime::pStep2 SbiRuntime::aStep2[] = {// all opcodes with two operand // SbiRTLData SbiRTLData::SbiRTLData() - : nDirFlags(SbAttributes::NONE) + : nDirFlags(SbAttributes::NORMAL) , nCurDirPos(0) { } @@ -384,6 +373,8 @@ SbiDllMgr* SbiInstance::GetDllMgr() return pDllMgr.get(); } +#endif + // #39629 create NumberFormatter with the help of a static method now std::shared_ptr<SvNumberFormatter> const & SbiInstance::GetNumberFormatter() { @@ -476,6 +467,7 @@ std::shared_ptr<SvNumberFormatter> SbiInstance::PrepareNumberFormatter( sal_uInt return pNumberFormatter; } +#if HAVE_FEATURE_SCRIPTING // Let engine run. If Flags == BasicDebugFlags::Continue, take Flags over @@ -598,32 +590,14 @@ SbMethod* SbiInstance::GetCaller( sal_uInt16 nLevel ) SbiRuntime::SbiRuntime( SbModule* pm, SbMethod* pe, sal_uInt32 nStart ) : rBasic( *static_cast<StarBASIC*>(pm->pParent) ), pInst( GetSbData()->pInst ), - pMod( pm ), pMeth( pe ), pImg( pMod->pImage.get() ), mpExtCaller(nullptr), m_nLastTime(0) + pMod( pm ), pMeth( pe ), pImg( pMod->pImage.get() ) { nFlags = pe ? pe->GetDebugFlags() : BasicDebugFlags::NONE; pIosys = pInst->GetIoSystem(); - pForStk = nullptr; - pError = nullptr; - pErrCode = - pErrStmnt = - pRestart = nullptr; - pNext = nullptr; pCode = pStmnt = pImg->GetCode() + nStart; - bRun = - bError = true; - bInError = false; - bBlocked = false; - nLine = 0; - nCol1 = 0; - nCol2 = 0; - nExprLvl = 0; - nArgc = 0; - nError = ERRCODE_NONE; - nForLvl = 0; - nOps = 0; refExprStk = new SbxArray; - SetVBAEnabled( pMod->IsVBACompat() ); + SetVBAEnabled( pMod->IsVBASupport() ); SetParameters( pe ? pe->GetParameters() : nullptr ); } @@ -706,6 +680,7 @@ void SbiRuntime::SetParameters( SbxArray* pParams ) } SbxVariable* v = pParams->Get(i); + assert(v); // methods are always byval! bool bByVal = dynamic_cast<const SbxMethod *>(v) != nullptr; SbxDataType t = v->GetType(); @@ -791,23 +766,26 @@ bool SbiRuntime::Step() { if( bRun ) { + static sal_uInt32 nLastTime = osl_getGlobalTimer(); + // in any case check casually! if( !( ++nOps & 0xF ) && pInst->IsReschedule() ) { sal_uInt32 nTime = osl_getGlobalTimer(); - if (nTime - m_nLastTime > 5 ) // 20 ms + if (nTime - nLastTime > 5) // 20 ms { + nLastTime = nTime; Application::Reschedule(); - m_nLastTime = nTime; } } // #i48868 blocked by next call level? while( bBlocked ) { - if( pInst->IsReschedule() ) + if( pInst->IsReschedule() ) // And what if not? Busy loop? { Application::Reschedule(); + nLastTime = osl_getGlobalTimer(); } } @@ -1151,6 +1129,17 @@ void SbiRuntime::PushFor() p->refInc = PopVar(); p->refEnd = PopVar(); + if (isVBAEnabled()) + { + // tdf#150458: only calculate these once, coercing to double + // tdf#150460: shouldn't we do it in non-VBA / compat mode, too? + SbxVariableRef incCopy(new SbxVariable(SbxDOUBLE)); + *incCopy = *p->refInc; + p->refInc = std::move(incCopy); + SbxVariableRef endCopy(new SbxVariable(SbxDOUBLE)); + *endCopy = *p->refEnd; + p->refEnd = std::move(endCopy); + } SbxVariableRef xBgn = PopVar(); p->refVar = PopVar(); // tdf#85371 - grant explicitly write access to the index variable @@ -1169,7 +1158,15 @@ void SbiRuntime::PushForEach() pForStk = p; SbxVariableRef xObjVar = PopVar(); - SbxBase* pObj = xObjVar && xObjVar->GetFullType() == SbxOBJECT ? xObjVar->GetObject() : nullptr; + SbxBase* pObj(nullptr); + if (xObjVar) + { + SbxValues v(SbxVARIANT); + // Here it may retrieve the value, and change the type from SbxEMPTY to SbxOBJECT + xObjVar->Get(v); + if (v.eType == SbxOBJECT) + pObj = v.pObj; + } if (SbxDimArray* pArray = dynamic_cast<SbxDimArray*>(pObj)) { @@ -1208,7 +1205,7 @@ void SbiRuntime::PushForEach() else if (aAny >>= xIndexAccess) { p->eForType = ForType::EachXIndexAccess; - p->xIndexAccess = xIndexAccess; + p->xIndexAccess = std::move(xIndexAccess); p->nCurCollectionIndex = 0; } else if ( isVBAEnabled() && pUnoObj->isNativeCOMObject() ) @@ -1279,8 +1276,6 @@ void SbiRuntime::DllCall SbxDataType eResType, // return value bool bCDecl ) // true: according to C-conventions { - // NOT YET IMPLEMENTED - SbxVariable* pRes = new SbxVariable( eResType ); SbiDllMgr* pDllMgr = pInst->GetDllMgr(); ErrCode nErr = pDllMgr->Call( aFuncName, aDLLName, pArgs, *pRes, bCDecl ); @@ -1451,101 +1446,68 @@ void SbiRuntime::StepGE() { StepCompare( SbxGE ); } namespace { - bool NeedEsc(sal_Unicode cCode) - { - if(!rtl::isAscii(cCode)) - { - return false; - } - switch(cCode) - { - case '.': - case '^': - case '$': - case '+': - case '\\': - case '|': - case '{': - case '}': - case '(': - case ')': - return true; - default: - return false; - } - } - - OUString VBALikeToRegexp(const OUString &rIn) + OUString VBALikeToRegexp(std::u16string_view sIn) { - OUStringBuffer sResult; - const sal_Unicode *start = rIn.getStr(); - const sal_Unicode *end = start + rIn.getLength(); - - int seenright = 0; + OUStringBuffer sResult("\\A"); // Match at the beginning of the input - sResult.append('^'); - - while (start < end) + for (auto start = sIn.begin(), end = sIn.end(); start < end;) { - switch (*start) + switch (auto ch = *start++) { case '?': sResult.append('.'); - start++; break; case '*': sResult.append(".*"); - start++; break; case '#': sResult.append("[0-9]"); - start++; - break; - case ']': - sResult.append('\\'); - sResult.append(*start++); break; case '[': - sResult.append(*start++); - seenright = 0; - while (start < end && !seenright) + sResult.append(ch); + if (start < end) + { + if (*start == '!') + { + sResult.append('^'); + ++start; + } + else if (*start == '^') + sResult.append('\\'); + } + for (bool seenright = false; start < end && !seenright; ++start) { switch (*start) { case '[': - case '?': - case '*': + case '\\': sResult.append('\\'); - sResult.append(*start); break; case ']': - sResult.append(*start); - seenright = 1; - break; - case '!': - sResult.append('^'); - break; - default: - if (NeedEsc(*start)) - { - sResult.append('\\'); - } - sResult.append(*start); + seenright = true; break; } - start++; + sResult.append(*start); } break; + case '.': + case '^': + case '$': + case '+': + case '\\': + case '|': + case '{': + case '}': + case '(': + case ')': + sResult.append('\\'); + [[fallthrough]]; default: - if (NeedEsc(*start)) - { - sResult.append('\\'); - } - sResult.append(*start++); + sResult.append(ch); } } - sResult.append('$'); + sResult.append("\\z"); // Match if the current position is at the end of input return sResult.makeStringAndClear(); } @@ -1556,15 +1518,8 @@ void SbiRuntime::StepLIKE() SbxVariableRef refVar1 = PopVar(); SbxVariableRef refVar2 = PopVar(); - OUString pattern = VBALikeToRegexp(refVar1->GetOUString()); OUString value = refVar2->GetOUString(); - - i18nutil::SearchOptions2 aSearchOpt; - - aSearchOpt.AlgorithmType2 = css::util::SearchAlgorithms2::REGEXP; - - aSearchOpt.Locale = Application::GetSettings().GetLanguageTag().getLocale(); - aSearchOpt.searchString = pattern; + OUString regex = VBALikeToRegexp(refVar1->GetOUString()); bool bTextMode(true); bool bCompatibility = ( GetSbData()->pInst && GetSbData()->pInst->IsCompatibility() ); @@ -1572,14 +1527,35 @@ void SbiRuntime::StepLIKE() { bTextMode = IsImageFlag( SbiImageFlags::COMPARETEXT ); } + sal_uInt32 searchFlags = UREGEX_UWORD | UREGEX_DOTALL; // Dot matches newline if( bTextMode ) { - aSearchOpt.transliterateFlags |= TransliterationFlags::IGNORE_CASE; + searchFlags |= UREGEX_CASE_INSENSITIVE; + } + + static sal_uInt32 cachedSearchFlags = 0; + static OUString cachedRegex; + static std::optional<icu::RegexMatcher> oRegexMatcher; + UErrorCode nIcuErr = U_ZERO_ERROR; + if (regex != cachedRegex || searchFlags != cachedSearchFlags || !oRegexMatcher) + { + cachedRegex = regex; + cachedSearchFlags = searchFlags; + icu::UnicodeString sRegex(false, reinterpret_cast<const UChar*>(cachedRegex.getStr()), + cachedRegex.getLength()); + oRegexMatcher.emplace(sRegex, cachedSearchFlags, nIcuErr); + } + + icu::UnicodeString sSource(false, reinterpret_cast<const UChar*>(value.getStr()), + value.getLength()); + oRegexMatcher->reset(sSource); + + bool bRes = oRegexMatcher->matches(nIcuErr); + if (nIcuErr) + { + Error(ERRCODE_BASIC_INTERNAL_ERROR); } SbxVariable* pRes = new SbxVariable; - utl::TextSearch aSearch( aSearchOpt); - sal_Int32 nStart=0, nEnd=value.getLength(); - bool bRes = aSearch.SearchForward(value, &nStart, &nEnd); pRes->PutBool( bRes ); PushVar( pRes ); @@ -1666,40 +1642,39 @@ static bool checkUnoStructCopy( bool bVBA, SbxVariableRef const & refVal, SbxVar aAny = pUnoVal ? pUnoVal->getUnoAny() : pUnoStructVal->getUnoAny(); else return false; - if ( aAny.getValueType().getTypeClass() == TypeClass_STRUCT ) - { - refVar->SetType( SbxOBJECT ); - ErrCode eOldErr = SbxBase::GetError(); - // There are some circumstances when calling GetObject - // will trigger an error, we need to squash those here. - // Alternatively it is possible that the same scenario - // could overwrite and existing error. Lets prevent that - SbxObjectRef xVarObj = static_cast<SbxObject*>(refVar->GetObject()); - if ( eOldErr != ERRCODE_NONE ) - SbxBase::SetError( eOldErr ); - else - SbxBase::ResetError(); + if ( aAny.getValueTypeClass() != TypeClass_STRUCT ) + return false; - SbUnoStructRefObject* pUnoStructObj = dynamic_cast<SbUnoStructRefObject*>( xVarObj.get() ); + refVar->SetType( SbxOBJECT ); + ErrCode eOldErr = SbxBase::GetError(); + // There are some circumstances when calling GetObject + // will trigger an error, we need to squash those here. + // Alternatively it is possible that the same scenario + // could overwrite and existing error. Let's prevent that + SbxObjectRef xVarObj = static_cast<SbxObject*>(refVar->GetObject()); + if ( eOldErr != ERRCODE_NONE ) + SbxBase::SetError( eOldErr ); + else + SbxBase::ResetError(); - OUString sClassName = pUnoVal ? pUnoVal->GetClassName() : pUnoStructVal->GetClassName(); - OUString sName = pUnoVal ? pUnoVal->GetName() : pUnoStructVal->GetName(); + SbUnoStructRefObject* pUnoStructObj = dynamic_cast<SbUnoStructRefObject*>( xVarObj.get() ); - if ( pUnoStructObj ) - { - StructRefInfo aInfo = pUnoStructObj->getStructInfo(); - aInfo.setValue( aAny ); - } - else - { - SbUnoObject* pNewUnoObj = new SbUnoObject( sName, aAny ); - // #70324: adopt ClassName - pNewUnoObj->SetClassName( sClassName ); - refVar->PutObject( pNewUnoObj ); - } - return true; + OUString sClassName = pUnoVal ? pUnoVal->GetClassName() : pUnoStructVal->GetClassName(); + OUString sName = pUnoVal ? pUnoVal->GetName() : pUnoStructVal->GetName(); + + if ( pUnoStructObj ) + { + StructRefInfo aInfo = pUnoStructObj->getStructInfo(); + aInfo.setValue( aAny ); + } + else + { + SbUnoObject* pNewUnoObj = new SbUnoObject( sName, aAny ); + // #70324: adopt ClassName + pNewUnoObj->SetClassName( sClassName ); + refVar->PutObject( pNewUnoObj ); } - return false; + return true; } @@ -1775,10 +1750,10 @@ struct DimAsNewRecoverItem , m_pClassModule( nullptr ) {} - DimAsNewRecoverItem( const OUString& rObjClass, const OUString& rObjName, + DimAsNewRecoverItem( OUString aObjClass, OUString aObjName, SbxObject* pObjParent, SbModule* pClassModule ) - : m_aObjClass( rObjClass ) - , m_aObjName( rObjName ) + : m_aObjClass(std::move( aObjClass )) + , m_aObjName(std::move( aObjName )) , m_pObjParent( pObjParent ) , m_pClassModule( pClassModule ) {} @@ -1816,7 +1791,7 @@ void removeDimAsNewRecoverItem( SbxVariable* pVar ) // saving object variable // not-object variables will cause errors -constexpr OUStringLiteral pCollectionStr = u"Collection"; +constexpr OUString pCollectionStr = u"Collection"_ustr; void SbiRuntime::StepSET_Impl( SbxVariableRef& refVal, SbxVariableRef& refVar, bool bHandleDefaultProp ) { @@ -1850,7 +1825,7 @@ void SbiRuntime::StepSET_Impl( SbxVariableRef& refVal, SbxVariableRef& refVar, b if( refObjVal.is() ) { - refVal = refObjVal; + refVal = std::move(refObjVal); } else if( !(eValType & SbxARRAY) ) { @@ -1985,7 +1960,7 @@ void SbiRuntime::StepSET_Impl( SbxVariableRef& refVal, SbxVariableRef& refVar, b const DimAsNewRecoverItem& rItem = it->second; if( rItem.m_pClassModule != nullptr ) { - SbClassModuleObject* pNewObj = new SbClassModuleObject( rItem.m_pClassModule ); + SbClassModuleObject* pNewObj = new SbClassModuleObject(*rItem.m_pClassModule); pNewObj->SetName( rItem.m_aObjName ); pNewObj->SetParent( rItem.m_pObjParent ); refVar->PutObject( pNewObj ); @@ -2015,9 +1990,9 @@ void SbiRuntime::StepSET_Impl( SbxVariableRef& refVal, SbxVariableRef& refVar, b SbClassModuleObject* pClassModuleObj = dynamic_cast<SbClassModuleObject*>( pValObjBase ); if( pClassModuleObj != nullptr ) { - SbModule* pClassModule = pClassModuleObj->getClassModule(); + SbModule& rClassModule = pClassModuleObj->getClassModule(); gaDimAsNewRecoverHash[refVar.get()] = - DimAsNewRecoverItem( aObjClass, pValObj->GetName(), pValObj->GetParent(), pClassModule ); + DimAsNewRecoverItem( aObjClass, pValObj->GetName(), pValObj->GetParent(), &rClassModule ); } else if( aObjClass.equalsIgnoreAsciiCase( "Collection" ) ) { @@ -2546,7 +2521,7 @@ void SbiRuntime::StepINPUT() // then with a string value if( !pVar->IsFixed() || pVar->IsNumeric() ) { - sal_uInt16 nLen = 0; + sal_Int32 nLen = 0; if( !pVar->Scan( s, &nLen ) ) { err = SbxBase::GetError(); @@ -2745,7 +2720,7 @@ void SbiRuntime::StepPRINTF() // print TOS in field } s.append(s1); comphelper::string::padToLength(s, 14, ' '); - pIosys->Write( s.makeStringAndClear() ); + pIosys->Write( s ); Error( pIosys->GetError() ); } @@ -2798,8 +2773,7 @@ void SbiRuntime::StepRENAME() // Rename Tos+1 to Tos void SbiRuntime::StepPROMPT() { SbxVariableRef p = PopVar(); - OString aStr(OUStringToOString(p->GetOUString(), osl_getThreadTextEncoding())); - pIosys->SetPrompt( aStr ); + pIosys->SetPrompt(p->GetOUString()); } // Set Restart point @@ -2848,7 +2822,7 @@ void SbiRuntime::StepLOADNC( sal_uInt32 nOp1 ) // tdf#143707 - check if the data type character was added after the string termination symbol SbxDataType eTypeStr; // #57844 use localized function - OUString aStr = pImg->GetString(static_cast<short>(nOp1), &eTypeStr); + OUString aStr = pImg->GetString(nOp1, &eTypeStr); // also allow , !!! sal_Int32 iComma = aStr.indexOf(','); if( iComma >= 0 ) @@ -2894,7 +2868,7 @@ void SbiRuntime::StepLOADNC( sal_uInt32 nOp1 ) void SbiRuntime::StepLOADSC( sal_uInt32 nOp1 ) { SbxVariable* p = new SbxVariable; - p->PutString( pImg->GetString( static_cast<short>( nOp1 ) ) ); + p->PutString( pImg->GetString( nOp1 ) ); PushVar( p ); } @@ -2916,7 +2890,7 @@ void SbiRuntime::StepARGN( sal_uInt32 nOp1 ) StarBASIC::FatalError( ERRCODE_BASIC_INTERNAL_ERROR ); else { - OUString aAlias( pImg->GetString( static_cast<short>( nOp1 ) ) ); + OUString aAlias( pImg->GetString( nOp1 ) ); SbxVariableRef pVal = PopVar(); if( bVBAEnabled && ( dynamic_cast<const SbxMethod*>( pVal.get()) != nullptr @@ -3000,6 +2974,11 @@ void SbiRuntime::StepPAD( sal_uInt32 nOp1 ) comphelper::string::padToLength(aBuf, nLen, ' '); } s = aBuf.makeStringAndClear(); + // Do not modify the original variable inadvertently + PopVar(); + p = new SbxVariable; + p->PutString(s); + PushVar(p); } // jump (+target) @@ -3024,6 +3003,14 @@ bool SbiRuntime::EvaluateTopOfStackAsBool() { return false; } + + // tdf#151503 - do not evaluate a missing optional variable to a boolean + if (tos->GetType() == SbxERROR && IsMissing(tos.get(), 1)) + { + Error(ERRCODE_BASIC_NOT_OPTIONAL); + return false; + } + if ( tos->IsObject() ) { //GetBool applied to an Object attempts to dereference and evaluate @@ -3069,13 +3056,16 @@ void SbiRuntime::StepONJUMP( sal_uInt32 nOp1 ) { SbxVariableRef p = PopVar(); sal_Int16 n = p->GetInteger(); - if( nOp1 & 0x8000 ) - { + + if (nOp1 & 0x8000) nOp1 &= 0x7FFF; - PushGosub( pCode + 5 * nOp1 ); - } - if( n < 1 || o3tl::make_unsigned(n) > nOp1 ) - n = static_cast<sal_Int16>( nOp1 + 1 ); + + // tdf#160321 - do not execute the jump statement if the expression is out of range + if (n < 1 || o3tl::make_unsigned(n) > nOp1) + n = static_cast<sal_Int16>(nOp1 + 1); + else if (nOp1 & 0x8000) + PushGosub(pCode + 5 * nOp1); + nOp1 = static_cast<sal_uInt32>(pCode - pImg->GetCode()) + 5 * --n; StepJUMP( nOp1 ); } @@ -3427,7 +3417,7 @@ void SbiRuntime::StepSETCLASS_impl( sal_uInt32 nOp1, bool bHandleDflt ) { SbxVariableRef refVal = PopVar(); SbxVariableRef refVar = PopVar(); - OUString aClass( pImg->GetString( static_cast<short>( nOp1 ) ) ); + OUString aClass( pImg->GetString( nOp1 ) ); bool bOk = checkClass_Impl( refVal, aClass, true, true ); if( bOk ) @@ -3449,7 +3439,7 @@ void SbiRuntime::StepSETCLASS( sal_uInt32 nOp1 ) void SbiRuntime::StepTESTCLASS( sal_uInt32 nOp1 ) { SbxVariableRef xObjVal = PopVar(); - OUString aClass( pImg->GetString( static_cast<short>( nOp1 ) ) ); + OUString aClass( pImg->GetString( nOp1 ) ); bool bDefault = !bVBAEnabled; bool bOk = checkClass_Impl( xObjVal, aClass, false, bDefault ); @@ -3462,7 +3452,7 @@ void SbiRuntime::StepTESTCLASS( sal_uInt32 nOp1 ) void SbiRuntime::StepLIB( sal_uInt32 nOp1 ) { - aLibName = pImg->GetString( static_cast<short>( nOp1 ) ); + aLibName = pImg->GetString( nOp1 ); } // TOS is incremented by BASE, BASE is pushed before (+BASE) @@ -3516,7 +3506,7 @@ SbxVariable* SbiRuntime::FindElement( SbxObject* pObj, sal_uInt32 nOp1, sal_uInt { bool bFatalError = false; SbxDataType t = static_cast<SbxDataType>(nOp2); - OUString aName( pImg->GetString( static_cast<short>( nOp1 & 0x7FFF ) ) ); + OUString aName( pImg->GetString( nOp1 & 0x7FFF ) ); // Hacky capture of Evaluate [] syntax // this should be tackled I feel at the pcode level if ( bIsVBAInterOp && aName.startsWith("[") ) @@ -3721,7 +3711,7 @@ SbxVariable* SbiRuntime::FindElement( SbxObject* pObj, sal_uInt32 nOp1, sal_uInt } // consider index-access for UnoObjects // definitely we want this for VBA where properties are often - // collections ( which need index access ), but lets only do + // collections ( which need index access ), but let's only do // this if we actually have params following else if( bVBAEnabled && dynamic_cast<const SbUnoProperty*>( pElem) != nullptr && pElem->GetParameters() ) { @@ -3785,7 +3775,7 @@ SbxBase* SbiRuntime::FindElementExtern( const OUString& rName ) { // Parameter is missing pElem = new SbxVariable( SbxSTRING ); - pElem->PutString( "<missing parameter>"); + pElem->PutString( u"<missing parameter>"_ustr); } else { @@ -3875,7 +3865,7 @@ void SbiRuntime::SetupArgs( SbxVariable* p, sal_uInt32 nOp1 ) { Any aAny = pUnoObj->getUnoAny(); - if( aAny.getValueType().getTypeClass() == TypeClass_INTERFACE ) + if( aAny.getValueTypeClass() == TypeClass_INTERFACE ) { Reference< XDefaultMethod > xDfltMethod( aAny, UNO_QUERY ); @@ -3951,33 +3941,44 @@ void SbiRuntime::SetupArgs( SbxVariable* p, sal_uInt32 nOp1 ) SbxVariable* SbiRuntime::CheckArray( SbxVariable* pElem ) { - SbxArray* pPar; + assert(pElem); if( ( pElem->GetType() & SbxARRAY ) && refRedim.get() != pElem ) { SbxBase* pElemObj = pElem->GetObject(); - SbxDimArray* pDimArray = dynamic_cast<SbxDimArray*>( pElemObj ); - pPar = pElem->GetParameters(); - if( pDimArray ) + SbxArray* pPar = pElem->GetParameters(); + if (SbxDimArray* pDimArray = dynamic_cast<SbxDimArray*>(pElemObj)) { // parameters may be missing, if an array is // passed as an argument if( pPar ) - pElem = pDimArray->Get( pPar ); - } - else - { - SbxArray* pArray = dynamic_cast<SbxArray*>( pElemObj ); - if( pArray ) { - if( !pPar ) + bool parIsArrayIndex = true; + if (dynamic_cast<const SbxMethod*>(pElem)) { - Error( ERRCODE_BASIC_OUT_OF_RANGE ); - pElem = new SbxVariable; - } - else - { - pElem = pArray->Get(pPar->Get(1)->GetInteger()); + // If this was a method, then there are two possibilities: + // 1. pPar is this method's parameters. + // 2. pPar is the indexes into the array returned from the method. + // To disambiguate, check the 0th element of pPar. + if (dynamic_cast<const SbxMethod*>(pPar->Get(0))) + { + // pPar was the parameters to the method, not indexes into the array + parIsArrayIndex = false; + } } + if (parIsArrayIndex) + pElem = pDimArray->Get(pPar); + } + } + else if (SbxArray* pArray = dynamic_cast<SbxArray*>(pElemObj)) + { + if( !pPar ) + { + Error( ERRCODE_BASIC_OUT_OF_RANGE ); + pElem = new SbxVariable; + } + else + { + pElem = pArray->Get(pPar->Get(1)->GetInteger()); } } @@ -3992,8 +3993,7 @@ SbxVariable* SbiRuntime::CheckArray( SbxVariable* pElem ) dynamic_cast<const SbxMethod*>( pElem) == nullptr && ( !bVBAEnabled || dynamic_cast<const SbxProperty*>( pElem) == nullptr ) ) { - pPar = pElem->GetParameters(); - if ( pPar ) + if (SbxArray* pPar = pElem->GetParameters()) { // is it a uno-object? SbxBaseRef pObj = pElem->GetObject(); @@ -4003,7 +4003,7 @@ SbxVariable* SbiRuntime::CheckArray( SbxVariable* pElem ) { Any aAny = pUnoObj->getUnoAny(); - if( aAny.getValueType().getTypeClass() == TypeClass_INTERFACE ) + if( aAny.getValueTypeClass() == TypeClass_INTERFACE ) { Reference< XIndexAccess > xIndexAccess( aAny, UNO_QUERY ); if ( !bVBAEnabled ) @@ -4069,8 +4069,8 @@ SbxVariable* SbiRuntime::CheckArray( SbxVariable* pElem ) pUnoObj = pSbObj; Any aUnoAny = pUnoObj->getUnoAny(); - if( aUnoAny.getValueType().getTypeClass() == TypeClass_INTERFACE ) - x = aUnoAny; + if( aUnoAny.getValueTypeClass() == TypeClass_INTERFACE ) + x = std::move(aUnoAny); pElem = pDflt; } } @@ -4308,7 +4308,7 @@ void SbiRuntime::StepCASEIS( sal_uInt32 nOp1, sal_uInt32 nOp2 ) void SbiRuntime::StepCALL( sal_uInt32 nOp1, sal_uInt32 nOp2 ) { - OUString aName = pImg->GetString( static_cast<short>( nOp1 & 0x7FFF ) ); + OUString aName = pImg->GetString( nOp1 & 0x7FFF ); SbxArray* pArgs = nullptr; if( nOp1 & 0x8000 ) { @@ -4326,7 +4326,7 @@ void SbiRuntime::StepCALL( sal_uInt32 nOp1, sal_uInt32 nOp2 ) void SbiRuntime::StepCALLC( sal_uInt32 nOp1, sal_uInt32 nOp2 ) { - OUString aName = pImg->GetString( static_cast<short>( nOp1 & 0x7FFF ) ); + OUString aName = pImg->GetString( nOp1 & 0x7FFF ); SbxArray* pArgs = nullptr; if( nOp1 & 0x8000 ) { @@ -4416,7 +4416,7 @@ void SbiRuntime::StepSTMNT( sal_uInt32 nOp1, sal_uInt32 nOp2 ) } // 16.10.96: #31460 new concept for StepInto/Over/Out - // see explanation at _ImplGetBreakCallLevel + // see explanation at SbiInstance::CalcBreakCallLevel if( pInst->nCallLvl <= pInst->nBreakCallLvl ) { StarBASIC* pStepBasic = GetCurrentBasic( &rBasic ); @@ -4449,7 +4449,7 @@ void SbiRuntime::StepOPEN( sal_uInt32 nOp1, sal_uInt32 nOp2 ) SbxVariableRef pLen = PopVar(); short nBlkLen = pLen->GetInteger(); short nChan = pChan->GetInteger(); - OString aName(OUStringToOString(pName->GetOUString(), osl_getThreadTextEncoding())); + OUString aName = pName->GetOUString(); pIosys->Open( nChan, aName, static_cast<StreamMode>( nOp1 ), static_cast<SbiStreamFlags>( nOp2 ), nBlkLen ); Error( pIosys->GetError() ); @@ -4459,7 +4459,7 @@ void SbiRuntime::StepOPEN( sal_uInt32 nOp1, sal_uInt32 nOp2 ) void SbiRuntime::StepCREATE( sal_uInt32 nOp1, sal_uInt32 nOp2 ) { - OUString aClass( pImg->GetString( static_cast<short>( nOp2 ) ) ); + OUString aClass( pImg->GetString( nOp2 ) ); SbxObjectRef pObj = SbxBase::CreateObject( aClass ); if( !pObj ) { @@ -4467,7 +4467,7 @@ void SbiRuntime::StepCREATE( sal_uInt32 nOp1, sal_uInt32 nOp2 ) } else { - OUString aName( pImg->GetString( static_cast<short>( nOp1 ) ) ); + OUString aName( pImg->GetString( nOp1 ) ); pObj->SetName( aName ); // the object must be able to call the BASIC pObj->SetParent( &rBasic ); @@ -4529,7 +4529,7 @@ void SbiRuntime::StepDCREATE_IMPL( sal_uInt32 nOp1, sal_uInt32 nOp2 ) nTotalSize = 0; // on error, don't create objects // create objects and insert them into the array - OUString aClass( pImg->GetString( static_cast<short>( nOp2 ) ) ); + OUString aClass( pImg->GetString( nOp2 ) ); OUString aName; for( sal_Int32 i = 0 ; i < nTotalSize ; ++i ) { @@ -4544,7 +4544,7 @@ void SbiRuntime::StepDCREATE_IMPL( sal_uInt32 nOp1, sal_uInt32 nOp2 ) else { if (aName.isEmpty()) - aName = pImg->GetString(static_cast<short>(nOp1)); + aName = pImg->GetString(nOp1); pClassObj->SetName(aName); // the object must be able to call the basic pClassObj->SetParent(&rBasic); @@ -4556,8 +4556,8 @@ void SbiRuntime::StepDCREATE_IMPL( sal_uInt32 nOp1, sal_uInt32 nOp2 ) void SbiRuntime::StepTCREATE( sal_uInt32 nOp1, sal_uInt32 nOp2 ) { - OUString aName( pImg->GetString( static_cast<short>( nOp1 ) ) ); - OUString aClass( pImg->GetString( static_cast<short>( nOp2 ) ) ); + OUString aName( pImg->GetString( nOp1 ) ); + OUString aClass( pImg->GetString( nOp2 ) ); SbxObjectRef pCopyObj = createUserTypeImpl( aClass ); if( pCopyObj ) @@ -4586,7 +4586,7 @@ void SbiRuntime::implHandleSbxFlags( SbxVariable* pVar, SbxDataType t, sal_uInt3 if( bFixedString ) { sal_uInt16 nCount = static_cast<sal_uInt16>( nOp2 >> 17 ); // len = all bits above 0x10000 - OUStringBuffer aBuf; + OUStringBuffer aBuf(nCount); comphelper::string::padToLength(aBuf, nCount); pVar->PutString(aBuf.makeStringAndClear()); } @@ -4606,7 +4606,7 @@ void SbiRuntime::StepLOCAL( sal_uInt32 nOp1, sal_uInt32 nOp2 ) { refLocals = new SbxArray; } - OUString aName( pImg->GetString( static_cast<short>( nOp1 ) ) ); + OUString aName( pImg->GetString( nOp1 ) ); if( refLocals->Find( aName, SbxClassType::DontCare ) == nullptr ) { SbxDataType t = static_cast<SbxDataType>(nOp2 & 0xffff); @@ -4621,7 +4621,7 @@ void SbiRuntime::StepLOCAL( sal_uInt32 nOp1, sal_uInt32 nOp2 ) void SbiRuntime::StepPUBLIC_Impl( sal_uInt32 nOp1, sal_uInt32 nOp2, bool bUsedForClassModule ) { - OUString aName( pImg->GetString( static_cast<short>( nOp1 ) ) ); + OUString aName( pImg->GetString( nOp1 ) ); SbxDataType t = static_cast<SbxDataType>(nOp2 & 0xffff); bool bFlag = pMod->IsSet( SbxFlagBits::NoModify ); pMod->SetFlag( SbxFlagBits::NoModify ); @@ -4673,7 +4673,7 @@ void SbiRuntime::StepGLOBAL( sal_uInt32 nOp1, sal_uInt32 nOp2 ) { StepPUBLIC_Impl( nOp1, nOp2, true ); } - OUString aName( pImg->GetString( static_cast<short>( nOp1 ) ) ); + OUString aName( pImg->GetString( nOp1 ) ); SbxDataType t = static_cast<SbxDataType>(nOp2 & 0xffff); // Store module scope variables at module scope @@ -4733,7 +4733,7 @@ void SbiRuntime::StepFIND_G( sal_uInt32 nOp1, sal_uInt32 nOp2 ) { // Return dummy variable SbxDataType t = static_cast<SbxDataType>(nOp2); - OUString aName( pImg->GetString( static_cast<short>( nOp1 & 0x7FFF ) ) ); + OUString aName( pImg->GetString( nOp1 & 0x7FFF ) ); SbxVariable* pDummyVar = new SbxVariable( t ); pDummyVar->SetName( aName ); @@ -4766,9 +4766,11 @@ SbxVariable* SbiRuntime::StepSTATIC_Impl( // establishing a static variable (+StringID+type) void SbiRuntime::StepSTATIC( sal_uInt32 nOp1, sal_uInt32 nOp2 ) { - OUString aName( pImg->GetString( static_cast<short>( nOp1 ) ) ); + OUString aName( pImg->GetString( nOp1 ) ); SbxDataType t = static_cast<SbxDataType>(nOp2 & 0xffff); StepSTATIC_Impl( aName, t, nOp2 ); } +#endif + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/basic/source/runtime/stdobj.cxx b/basic/source/runtime/stdobj.cxx index 1a2499cde2da..f30a633dccfb 100644 --- a/basic/source/runtime/stdobj.cxx +++ b/basic/source/runtime/stdobj.cxx @@ -34,29 +34,38 @@ // does NOT impose a limit on User defined procedures ). This changes is to // allow us space for a flag to denylist some functions in vba mode -#define ARGSMASK_ 0x003F // 63 Arguments -#define COMPTMASK_ 0x00C0 // COMPATIBILITY mask -#define COMPATONLY_ 0x0080 // procedure is visible in vba mode only -#define NORMONLY_ 0x0040 // procedure is visible in normal mode only - -#define RWMASK_ 0x0F00 // mask for R/W-bits -#define TYPEMASK_ 0xF000 // mask for the entry's type - -#define OPT_ 0x0400 // parameter is optional -#define CONST_ 0x0800 // property is const -#define METHOD_ 0x3000 -#define PROPERTY_ 0x4000 -#define OBJECT_ 0x8000 - // combination of bits above: -#define FUNCTION_ 0x1100 -#define LFUNCTION_ 0x1300 // mask for function which also works as Lvalue -#define SUB_ 0x2100 -#define ROPROP_ 0x4100 // mask Read Only-Property -#define RWPROP_ 0x4300 // mask Read/Write-Property -#define CPROP_ 0x4900 // mask for constant - namespace { +enum Flags +{ + ARGSMASK_ = 0x003F, // 63 Arguments + + NORMONLY_ = 0x0040, // procedure is visible in normal mode only + COMPATONLY_ = 0x0080, // procedure is visible in vba mode only + COMPTMASK_ = (COMPATONLY_ | NORMONLY_), // COMPATIBILITY mask + + READ_ = 0x0100, // parameter allows read + WRITE_ = 0x0200, // parameter allows write + OPT_ = 0x0400, // parameter is optional + CONST_ = 0x0800, // property is const + RWMASK_ = (READ_ | WRITE_ | OPT_ | CONST_), // mask for R/W-bits + + FUNC_TYPE_ = 0x1000, // functional type + SUB_TYPE_ = 0x2000, // sub type + METHOD_ = (FUNC_TYPE_ | SUB_TYPE_), + PROPERTY_ = 0x4000, + OBJECT_ = 0x8000, + TYPEMASK_ = (METHOD_ | PROPERTY_ | OBJECT_), // mask for the entry's type + + // combination of bits above + FUNCTION_ = (FUNC_TYPE_ | READ_), + LFUNCTION_ = (FUNC_TYPE_ | READ_ | WRITE_), // mask for function which also works as Lvalue (statement) + SUB_ = SUB_TYPE_, + ROPROP_ = (PROPERTY_ | READ_), // mask Read Only-Property + RWPROP_ = (PROPERTY_ | READ_ | WRITE_), // mask Read/Write-Property + CPROP_ = (PROPERTY_ | READ_ | CONST_) // mask for constant +}; + struct Method { RtlCall pFunc; std::u16string_view sName; @@ -82,20 +91,9 @@ template <int N> constexpr bool MethodsTableValid(const Method (&rMethods)[N]) { int nCurMethArgs = 0; int nArgsChecked = 0; - bool bFinished = false; for (const auto& m : rMethods) { - assert(!bFinished); // no entries after end-of-table entry - if (bFinished) - return false; - if (m.nArgs == -1) // end-of-table entry - { - assert(nCurMethArgs == nArgsChecked); // last method had correct # of arguments - if (nCurMethArgs != nArgsChecked) - return false; - bFinished = true; - } - else if (m.pFunc) // main (function/sub/etc) entry + if (m.pFunc) // main (function/sub/etc) entry { assert(nCurMethArgs == nArgsChecked); // previous method had correct # of arguments if (nCurMethArgs != nArgsChecked) @@ -106,11 +104,12 @@ template <int N> constexpr bool MethodsTableValid(const Method (&rMethods)[N]) else // subordinate (argument) entry ++nArgsChecked; } - assert(bFinished); // its last entry was end-of-table entry - return bFinished; + assert(nCurMethArgs == nArgsChecked); // last method had correct # of arguments + return nCurMethArgs == nArgsChecked; } -} +template <bool N> void ConstBool(StarBASIC*, SbxArray& par, bool) { par.Get(0)->PutBool(N); } +template <sal_Int16 N> void ConstInt(StarBASIC*, SbxArray& par, bool) { par.Get(0)->PutInteger(N); } constexpr Method aMethods[] = { @@ -127,13 +126,14 @@ constexpr Method aMethods[] = { { u"Atn", SbxDOUBLE, 1 | FUNCTION_, SbRtl_Atn }, arg(u"number", SbxDOUBLE), -{ u"ATTR_ARCHIVE", SbxINTEGER, CPROP_, SbRtl_ATTR_ARCHIVE }, -{ u"ATTR_DIRECTORY", SbxINTEGER, CPROP_, SbRtl_ATTR_DIRECTORY }, -{ u"ATTR_HIDDEN", SbxINTEGER, CPROP_, SbRtl_ATTR_HIDDEN }, -{ u"ATTR_NORMAL", SbxINTEGER, CPROP_, SbRtl_ATTR_NORMAL }, -{ u"ATTR_READONLY", SbxINTEGER, CPROP_, SbRtl_ATTR_READONLY }, -{ u"ATTR_SYSTEM", SbxINTEGER, CPROP_, SbRtl_ATTR_SYSTEM }, -{ u"ATTR_VOLUME", SbxINTEGER, CPROP_, SbRtl_ATTR_VOLUME }, +// Related to: Dir, GetAttr, SetAttr +{ u"ATTR_ARCHIVE", SbxINTEGER, CPROP_, ConstInt<SbAttributes::ARCHIVE> }, +{ u"ATTR_DIRECTORY", SbxINTEGER, CPROP_, ConstInt<SbAttributes::DIRECTORY> }, +{ u"ATTR_HIDDEN", SbxINTEGER, CPROP_, ConstInt<SbAttributes::HIDDEN> }, +{ u"ATTR_NORMAL", SbxINTEGER, CPROP_, ConstInt<SbAttributes::NORMAL> }, +{ u"ATTR_READONLY", SbxINTEGER, CPROP_, ConstInt<SbAttributes::READONLY> }, +{ u"ATTR_SYSTEM", SbxINTEGER, CPROP_, ConstInt<SbAttributes::SYSTEM> }, +{ u"ATTR_VOLUME", SbxINTEGER, CPROP_, ConstInt<SbAttributes::VOLUME> }, { u"Beep", SbxNULL, FUNCTION_, SbRtl_Beep }, { u"Blue", SbxINTEGER, 1 | FUNCTION_ | NORMONLY_, SbRtl_Blue }, @@ -141,7 +141,7 @@ constexpr Method aMethods[] = { { u"CallByName", SbxVARIANT, 3 | FUNCTION_, SbRtl_CallByName }, arg(u"Object", SbxOBJECT), - arg(u"ProcedureName", SbxSTRING), + arg(u"ProcName", SbxSTRING), arg(u"CallType", SbxINTEGER), { u"CBool", SbxBOOL, 1 | FUNCTION_, SbRtl_CBool }, @@ -186,9 +186,11 @@ constexpr Method aMethods[] = { { u"CDbl", SbxDOUBLE, 1 | FUNCTION_, SbRtl_CDbl }, arg(u"expression", SbxVARIANT), -{ u"CF_BITMAP", SbxINTEGER, CPROP_, SbRtl_CF_BITMAP }, -{ u"CF_METAFILEPICT", SbxINTEGER, CPROP_, SbRtl_CF_METAFILEPICT }, -{ u"CF_TEXT", SbxINTEGER, CPROP_, SbRtl_CF_TEXT }, +// FIXME: CF_* are for what??? They duplicate WinAPI clipboard constants, but why? +{ u"CF_BITMAP", SbxINTEGER, CPROP_, ConstInt<1> }, +{ u"CF_METAFILEPICT", SbxINTEGER, CPROP_, ConstInt<2> }, +{ u"CF_TEXT", SbxINTEGER, CPROP_, ConstInt<3> }, + { u"ChDir", SbxNULL, 1 | FUNCTION_, SbRtl_ChDir }, arg(u"string", SbxSTRING), @@ -200,16 +202,19 @@ constexpr Method aMethods[] = { arg(u"Expression", SbxVARIANT), { u"Chr", SbxSTRING, 1 | FUNCTION_, SbRtl_Chr }, - arg(u"string", SbxINTEGER), + arg(u"charcode", SbxLONG), { u"ChrW", SbxSTRING, 1 | FUNCTION_ | COMPATONLY_, SbRtl_ChrW }, - arg(u"string", SbxINTEGER), + arg(u"charcode", SbxLONG), { u"CInt", SbxINTEGER, 1 | FUNCTION_, SbRtl_CInt }, arg(u"expression", SbxVARIANT), -{ u"CLEAR_ALLTABS", SbxINTEGER, CPROP_, SbRtl_CLEAR_ALLTABS }, -{ u"CLEAR_TAB", SbxINTEGER, CPROP_, SbRtl_CLEAR_TAB }, +// FIXME: what for are these??? +{ u"SET_TAB", SbxINTEGER, CPROP_, ConstInt<0> }, +{ u"CLEAR_TAB", SbxINTEGER, CPROP_, ConstInt<1> }, +{ u"CLEAR_ALLTABS", SbxINTEGER, CPROP_, ConstInt<2> }, + { u"CLng", SbxLONG, 1 | FUNCTION_, SbRtl_CLng }, arg(u"expression", SbxVARIANT), @@ -328,8 +333,8 @@ constexpr Method aMethods[] = { { u"Ddeterminateall", SbxNULL, FUNCTION_, SbRtl_DDETerminateAll }, { u"DimArray", SbxOBJECT, FUNCTION_, SbRtl_DimArray }, { u"Dir", SbxSTRING, 2 | FUNCTION_, SbRtl_Dir }, - arg(u"FileSpec", SbxSTRING, OPT_), - arg(u"attrmask", SbxINTEGER, OPT_), + arg(u"Pathname", SbxSTRING, OPT_), + arg(u"Attributes", SbxINTEGER, OPT_), { u"DoEvents", SbxINTEGER, FUNCTION_, SbRtl_DoEvents }, { u"DumpAllObjects", SbxEMPTY, 2 | SUB_, SbRtl_DumpAllObjects }, @@ -358,7 +363,9 @@ constexpr Method aMethods[] = { { u"Exp", SbxDOUBLE, 1 | FUNCTION_, SbRtl_Exp }, arg(u"number", SbxDOUBLE), -{ u"False", SbxBOOL, CPROP_, SbRtl_False }, +{ u"False", SbxBOOL, CPROP_, ConstBool<false> }, +{ u"True", SbxBOOL, CPROP_, ConstBool<true> }, + { u"FileAttr", SbxINTEGER, 2 | FUNCTION_, SbRtl_FileAttr }, arg(u"Channel", SbxINTEGER), arg(u"Attributes", SbxINTEGER), @@ -401,12 +408,21 @@ constexpr Method aMethods[] = { arg(u"useParensForNegativeNumbers", SbxINTEGER, OPT_), // vbTriState arg(u"groupDigits", SbxINTEGER, OPT_), // vbTriState +{ u"FormatPercent", SbxSTRING, 5 | FUNCTION_ | COMPATONLY_, SbRtl_FormatPercent }, + arg(u"expression", SbxDOUBLE), + arg(u"numDigitsAfterDecimal", SbxINTEGER, OPT_), + arg(u"includeLeadingDigit", SbxINTEGER, OPT_), // vbTriState + arg(u"useParensForNegativeNumbers", SbxINTEGER, OPT_), // vbTriState + arg(u"groupDigits", SbxINTEGER, OPT_), // vbTriState + { u"Frac", SbxDOUBLE, 1 | FUNCTION_, SbRtl_Frac }, arg(u"number", SbxDOUBLE), -{ u"FRAMEANCHORCHAR", SbxINTEGER, CPROP_, SbRtl_FRAMEANCHORCHAR }, -{ u"FRAMEANCHORPAGE", SbxINTEGER, CPROP_, SbRtl_FRAMEANCHORPAGE }, -{ u"FRAMEANCHORPARA", SbxINTEGER, CPROP_, SbRtl_FRAMEANCHORPARA }, +// FIXME: what for are these??? +{ u"FRAMEANCHORPAGE", SbxINTEGER, CPROP_, ConstInt<1> }, +{ u"FRAMEANCHORCHAR", SbxINTEGER, CPROP_, ConstInt<15> }, +{ u"FRAMEANCHORPARA", SbxINTEGER, CPROP_, ConstInt<14> }, + { u"FreeFile", SbxINTEGER, FUNCTION_, SbRtl_FreeFile }, { u"FreeLibrary", SbxNULL, 1 | FUNCTION_, SbRtl_FreeLibrary }, arg(u"Modulename", SbxSTRING), @@ -449,12 +465,14 @@ constexpr Method aMethods[] = { { u"Hour", SbxINTEGER, 1 | FUNCTION_, SbRtl_Hour }, arg(u"Date", SbxDATE), -{ u"IDABORT", SbxINTEGER, CPROP_, SbRtl_IDABORT }, -{ u"IDCANCEL", SbxINTEGER, CPROP_, SbRtl_IDCANCEL }, -{ u"IDNO", SbxINTEGER, CPROP_, SbRtl_IDNO }, -{ u"IDOK", SbxINTEGER, CPROP_, SbRtl_IDOK }, -{ u"IDRETRY", SbxINTEGER, CPROP_, SbRtl_IDRETRY }, -{ u"IDYES", SbxINTEGER, CPROP_, SbRtl_IDYES }, +// Related to: MsgBox (return value) +{ u"IDABORT", SbxINTEGER, CPROP_, ConstInt<SbMB::Response::ABORT> }, +{ u"IDCANCEL", SbxINTEGER, CPROP_, ConstInt<SbMB::Response::CANCEL> }, +{ u"IDIGNORE", SbxINTEGER, CPROP_, ConstInt<SbMB::Response::IGNORE> }, +{ u"IDNO", SbxINTEGER, CPROP_, ConstInt<SbMB::Response::NO> }, +{ u"IDOK", SbxINTEGER, CPROP_, ConstInt<SbMB::Response::OK> }, +{ u"IDRETRY", SbxINTEGER, CPROP_, ConstInt<SbMB::Response::RETRY> }, +{ u"IDYES", SbxINTEGER, CPROP_, ConstInt<SbMB::Response::YES> }, { u"Iif", SbxVARIANT, 3 | FUNCTION_, SbRtl_Iif }, arg(u"Bool", SbxBOOL), @@ -479,10 +497,10 @@ constexpr Method aMethods[] = { arg(u"Compare", SbxINTEGER, OPT_), { u"InStrRev", SbxLONG, 4 | FUNCTION_ | COMPATONLY_, SbRtl_InStrRev }, - arg(u"String1", SbxSTRING), - arg(u"String2", SbxSTRING), - arg(u"Start", SbxSTRING, OPT_), - arg(u"Compare", SbxINTEGER, OPT_), + arg(u"StringCheck", SbxSTRING), + arg(u"StringMatch", SbxSTRING), + arg(u"Start", SbxSTRING, OPT_), + arg(u"Compare", SbxINTEGER, OPT_), { u"Int", SbxDOUBLE, 1 | FUNCTION_, SbRtl_Int }, arg(u"number", SbxDOUBLE), @@ -527,8 +545,8 @@ constexpr Method aMethods[] = { arg(u"Variant", SbxVARIANT), { u"Join", SbxSTRING, 2 | FUNCTION_, SbRtl_Join }, - arg(u"list", SbxOBJECT), - arg(u"delimiter", SbxSTRING), + arg(u"SourceArray", SbxOBJECT), + arg(u"Delimiter", SbxSTRING), { u"Kill", SbxNULL, 1 | FUNCTION_, SbRtl_Kill }, arg(u"filespec", SbxSTRING), @@ -541,7 +559,7 @@ constexpr Method aMethods[] = { { u"Left", SbxSTRING, 2 | FUNCTION_, SbRtl_Left }, arg(u"String", SbxSTRING), - arg(u"Count", SbxLONG), + arg(u"Length", SbxLONG), { u"Len", SbxLONG, 1 | FUNCTION_, SbRtl_Len }, arg(u"StringOrVariant", SbxVARIANT), @@ -567,27 +585,28 @@ constexpr Method aMethods[] = { { u"LTrim", SbxSTRING, 1 | FUNCTION_, SbRtl_LTrim }, arg(u"string", SbxSTRING), -{ u"MB_ABORTRETRYIGNORE", SbxINTEGER, CPROP_, SbRtl_MB_ABORTRETRYIGNORE }, -{ u"MB_APPLMODAL", SbxINTEGER, CPROP_, SbRtl_MB_APPLMODAL }, -{ u"MB_DEFBUTTON1", SbxINTEGER, CPROP_, SbRtl_MB_DEFBUTTON1 }, -{ u"MB_DEFBUTTON2", SbxINTEGER, CPROP_, SbRtl_MB_DEFBUTTON2 }, -{ u"MB_DEFBUTTON3", SbxINTEGER, CPROP_, SbRtl_MB_DEFBUTTON3 }, -{ u"MB_ICONEXCLAMATION", SbxINTEGER, CPROP_, SbRtl_MB_ICONEXCLAMATION }, -{ u"MB_ICONINFORMATION", SbxINTEGER, CPROP_, SbRtl_MB_ICONINFORMATION }, -{ u"MB_ICONQUESTION", SbxINTEGER, CPROP_, SbRtl_MB_ICONQUESTION }, -{ u"MB_ICONSTOP", SbxINTEGER, CPROP_, SbRtl_MB_ICONSTOP }, -{ u"MB_OK", SbxINTEGER, CPROP_, SbRtl_MB_OK }, -{ u"MB_OKCANCEL", SbxINTEGER, CPROP_, SbRtl_MB_OKCANCEL }, -{ u"MB_RETRYCANCEL", SbxINTEGER, CPROP_, SbRtl_MB_RETRYCANCEL }, -{ u"MB_SYSTEMMODAL", SbxINTEGER, CPROP_, SbRtl_MB_SYSTEMMODAL }, -{ u"MB_YESNO", SbxINTEGER, CPROP_, SbRtl_MB_YESNO }, -{ u"MB_YESNOCANCEL", SbxINTEGER, CPROP_, SbRtl_MB_YESNOCANCEL }, +// Related to: MsgBox (Buttons argument) +{ u"MB_ABORTRETRYIGNORE", SbxINTEGER, CPROP_, ConstInt<SbMB::ABORTRETRYIGNORE> }, +{ u"MB_APPLMODAL", SbxINTEGER, CPROP_, ConstInt<SbMB::APPLMODAL> }, +{ u"MB_DEFBUTTON1", SbxINTEGER, CPROP_, ConstInt<SbMB::DEFBUTTON1> }, +{ u"MB_DEFBUTTON2", SbxINTEGER, CPROP_, ConstInt<SbMB::DEFBUTTON2> }, +{ u"MB_DEFBUTTON3", SbxINTEGER, CPROP_, ConstInt<SbMB::DEFBUTTON3> }, +{ u"MB_ICONEXCLAMATION", SbxINTEGER, CPROP_, ConstInt<SbMB::ICONEXCLAMATION> }, +{ u"MB_ICONINFORMATION", SbxINTEGER, CPROP_, ConstInt<SbMB::ICONINFORMATION> }, +{ u"MB_ICONQUESTION", SbxINTEGER, CPROP_, ConstInt<SbMB::ICONQUESTION> }, +{ u"MB_ICONSTOP", SbxINTEGER, CPROP_, ConstInt<SbMB::ICONSTOP> }, +{ u"MB_OK", SbxINTEGER, CPROP_, ConstInt<SbMB::OK> }, +{ u"MB_OKCANCEL", SbxINTEGER, CPROP_, ConstInt<SbMB::OKCANCEL> }, +{ u"MB_RETRYCANCEL", SbxINTEGER, CPROP_, ConstInt<SbMB::RETRYCANCEL> }, +{ u"MB_SYSTEMMODAL", SbxINTEGER, CPROP_, ConstInt<SbMB::SYSTEMMODAL> }, +{ u"MB_YESNO", SbxINTEGER, CPROP_, ConstInt<SbMB::YESNO> }, +{ u"MB_YESNOCANCEL", SbxINTEGER, CPROP_, ConstInt<SbMB::YESNOCANCEL> }, { u"Me", SbxOBJECT, 0 | FUNCTION_ | COMPATONLY_, SbRtl_Me }, { u"Mid", SbxSTRING, 3 | LFUNCTION_, SbRtl_Mid }, - arg(u"String", SbxSTRING), - arg(u"StartPos", SbxLONG), - arg(u"Length", SbxLONG, OPT_), + arg(u"String", SbxSTRING), + arg(u"Start", SbxLONG), + arg(u"Length", SbxLONG, OPT_), { u"Minute", SbxINTEGER, 1 | FUNCTION_, SbRtl_Minute }, arg(u"Date", SbxDATE), @@ -703,7 +722,7 @@ constexpr Method aMethods[] = { { u"Right", SbxSTRING, 2 | FUNCTION_, SbRtl_Right }, arg(u"String", SbxSTRING), - arg(u"Count", SbxLONG), + arg(u"Length", SbxLONG), { u"RmDir", SbxNULL, 1 | FUNCTION_, SbRtl_RmDir }, arg(u"pathname", SbxSTRING), @@ -734,18 +753,20 @@ constexpr Method aMethods[] = { arg(u"Wait", SbxBOOL, OPT_), { u"SetAttr", SbxNULL, 2 | FUNCTION_, SbRtl_SetAttr }, - arg(u"File", SbxSTRING), + arg(u"PathName", SbxSTRING), arg(u"Attributes", SbxINTEGER), -{ u"SET_OFF", SbxINTEGER, CPROP_, SbRtl_SET_OFF }, -{ u"SET_ON", SbxINTEGER, CPROP_, SbRtl_SET_ON }, -{ u"SET_TAB", SbxINTEGER, CPROP_, SbRtl_SET_TAB }, +// FIXME: what for are these??? +{ u"SET_OFF", SbxINTEGER, CPROP_, ConstInt<0> }, +{ u"SET_ON", SbxINTEGER, CPROP_, ConstInt<1> }, +{ u"TOGGLE", SbxINTEGER, CPROP_, ConstInt<2> }, + { u"Sgn", SbxINTEGER, 1 | FUNCTION_, SbRtl_Sgn }, arg(u"number", SbxDOUBLE), { u"Shell", SbxLONG, 2 | FUNCTION_, SbRtl_Shell }, - arg(u"Commandstring", SbxSTRING), - arg(u"WindowStyle", SbxINTEGER, OPT_), + arg(u"PathName", SbxSTRING), + arg(u"WindowStyle", SbxINTEGER, OPT_), { u"Sin", SbxDOUBLE, 1 | FUNCTION_, SbRtl_Sin }, arg(u"number", SbxDOUBLE), @@ -762,15 +783,15 @@ constexpr Method aMethods[] = { arg(u"Period", SbxDOUBLE), { u"Space", SbxSTRING, 1 | FUNCTION_, SbRtl_Space }, - arg(u"string", SbxLONG), + arg(u"Number", SbxLONG), -{ u"Spc", SbxSTRING, 1 | FUNCTION_, SbRtl_Spc }, - arg(u"Count", SbxLONG), +{ u"Spc", SbxSTRING, 1 | FUNCTION_, SbRtl_Space }, + arg(u"Number", SbxLONG), { u"Split", SbxOBJECT, 3 | FUNCTION_, SbRtl_Split }, arg(u"expression", SbxSTRING), arg(u"delimiter", SbxSTRING), - arg(u"count", SbxLONG), + arg(u"Limit", SbxLONG), { u"Sqr", SbxDOUBLE, 1 | FUNCTION_, SbRtl_Sqr }, arg(u"number", SbxDOUBLE), @@ -789,8 +810,8 @@ constexpr Method aMethods[] = { arg(u"LCID", SbxINTEGER, OPT_), { u"String", SbxSTRING, 2 | FUNCTION_, SbRtl_String }, - arg(u"Count", SbxLONG), - arg(u"Filler", SbxVARIANT), + arg(u"Number", SbxLONG), + arg(u"Character", SbxVARIANT), { u"StrReverse", SbxSTRING, 1 | FUNCTION_ | COMPATONLY_, SbRtl_StrReverse }, arg(u"String1", SbxSTRING), @@ -815,59 +836,58 @@ constexpr Method aMethods[] = { { u"TimeValue", SbxDATE, 1 | FUNCTION_, SbRtl_TimeValue }, arg(u"String", SbxSTRING), -{ u"TOGGLE", SbxINTEGER, CPROP_, SbRtl_TOGGLE }, { u"Trim", SbxSTRING, 1 | FUNCTION_, SbRtl_Trim }, arg(u"String", SbxSTRING), -{ u"True", SbxBOOL, CPROP_, SbRtl_True }, { u"TwipsPerPixelX", SbxLONG, FUNCTION_, SbRtl_TwipsPerPixelX }, { u"TwipsPerPixelY", SbxLONG, FUNCTION_, SbRtl_TwipsPerPixelY }, -{ u"TYP_AUTHORFLD", SbxINTEGER, CPROP_, SbRtl_TYP_AUTHORFLD }, -{ u"TYP_CHAPTERFLD", SbxINTEGER, CPROP_, SbRtl_TYP_CHAPTERFLD }, -{ u"TYP_CONDTXTFLD", SbxINTEGER, CPROP_, SbRtl_TYP_CONDTXTFLD }, -{ u"TYP_DATEFLD", SbxINTEGER, CPROP_, SbRtl_TYP_DATEFLD }, -{ u"TYP_DBFLD", SbxINTEGER, CPROP_, SbRtl_TYP_DBFLD }, -{ u"TYP_DBNAMEFLD", SbxINTEGER, CPROP_, SbRtl_TYP_DBNAMEFLD }, -{ u"TYP_DBNEXTSETFLD", SbxINTEGER, CPROP_, SbRtl_TYP_DBNEXTSETFLD }, -{ u"TYP_DBNUMSETFLD", SbxINTEGER, CPROP_, SbRtl_TYP_DBNUMSETFLD }, -{ u"TYP_DBSETNUMBERFLD", SbxINTEGER, CPROP_, SbRtl_TYP_DBSETNUMBERFLD }, -{ u"TYP_DDEFLD", SbxINTEGER, CPROP_, SbRtl_TYP_DDEFLD }, -{ u"TYP_DOCINFOFLD", SbxINTEGER, CPROP_, SbRtl_TYP_DOCINFOFLD }, -{ u"TYP_DOCSTATFLD", SbxINTEGER, CPROP_, SbRtl_TYP_DOCSTATFLD }, -{ u"TYP_EXTUSERFLD", SbxINTEGER, CPROP_, SbRtl_TYP_EXTUSERFLD }, -{ u"TYP_FILENAMEFLD", SbxINTEGER, CPROP_, SbRtl_TYP_FILENAMEFLD }, -{ u"TYP_FIXDATEFLD", SbxINTEGER, CPROP_, SbRtl_TYP_FIXDATEFLD }, -{ u"TYP_FIXTIMEFLD", SbxINTEGER, CPROP_, SbRtl_TYP_FIXTIMEFLD }, -{ u"TYP_FORMELFLD", SbxINTEGER, CPROP_, SbRtl_TYP_FORMELFLD }, -{ u"TYP_GETFLD", SbxINTEGER, CPROP_, SbRtl_TYP_GETFLD }, -{ u"TYP_GETREFFLD", SbxINTEGER, CPROP_, SbRtl_TYP_GETREFFLD }, -{ u"TYP_GETREFPAGEFLD", SbxINTEGER, CPROP_, SbRtl_TYP_GETREFPAGEFLD }, -{ u"TYP_HIDDENPARAFLD", SbxINTEGER, CPROP_, SbRtl_TYP_HIDDENPARAFLD }, -{ u"TYP_HIDDENTXTFLD", SbxINTEGER, CPROP_, SbRtl_TYP_HIDDENTXTFLD }, -{ u"TYP_INPUTFLD", SbxINTEGER, CPROP_, SbRtl_TYP_INPUTFLD }, -{ u"TYP_INTERNETFLD", SbxINTEGER, CPROP_, SbRtl_TYP_INTERNETFLD }, -{ u"TYP_JUMPEDITFLD", SbxINTEGER, CPROP_, SbRtl_TYP_JUMPEDITFLD }, -{ u"TYP_MACROFLD", SbxINTEGER, CPROP_, SbRtl_TYP_MACROFLD }, -{ u"TYP_NEXTPAGEFLD", SbxINTEGER, CPROP_, SbRtl_TYP_NEXTPAGEFLD }, -{ u"TYP_PAGENUMBERFLD", SbxINTEGER, CPROP_, SbRtl_TYP_PAGENUMBERFLD }, -{ u"TYP_POSTITFLD", SbxINTEGER, CPROP_, SbRtl_TYP_POSTITFLD }, -{ u"TYP_PREVPAGEFLD", SbxINTEGER, CPROP_, SbRtl_TYP_PREVPAGEFLD }, -{ u"TYP_SEQFLD", SbxINTEGER, CPROP_, SbRtl_TYP_SEQFLD }, -{ u"TYP_SETFLD", SbxINTEGER, CPROP_, SbRtl_TYP_SETFLD }, -{ u"TYP_SETINPFLD", SbxINTEGER, CPROP_, SbRtl_TYP_SETINPFLD }, -{ u"TYP_SETREFFLD", SbxINTEGER, CPROP_, SbRtl_TYP_SETREFFLD }, -{ u"TYP_SETREFPAGEFLD", SbxINTEGER, CPROP_, SbRtl_TYP_SETREFPAGEFLD }, -{ u"TYP_TEMPLNAMEFLD", SbxINTEGER, CPROP_, SbRtl_TYP_TEMPLNAMEFLD }, -{ u"TYP_TIMEFLD", SbxINTEGER, CPROP_, SbRtl_TYP_TIMEFLD }, -{ u"TYP_USERFLD", SbxINTEGER, CPROP_, SbRtl_TYP_USERFLD }, -{ u"TYP_USRINPFLD", SbxINTEGER, CPROP_, SbRtl_TYP_USRINPFLD }, +// Related to: SwFieldTypesEnum in sw/inc/fldbas.hxx, .uno:InsertField (Type param), .uno:InsertDBField (Type param) +{ u"TYP_AUTHORFLD", SbxINTEGER, CPROP_, ConstInt<SbTYP::AUTHOR> }, +{ u"TYP_CHAPTERFLD", SbxINTEGER, CPROP_, ConstInt<SbTYP::CHAPTER> }, +{ u"TYP_CONDTXTFLD", SbxINTEGER, CPROP_, ConstInt<SbTYP::CONDITIONALTEXT> }, +{ u"TYP_DATEFLD", SbxINTEGER, CPROP_, ConstInt<SbTYP::DATE> }, +{ u"TYP_DBFLD", SbxINTEGER, CPROP_, ConstInt<SbTYP::DATABASE> }, +{ u"TYP_DBNAMEFLD", SbxINTEGER, CPROP_, ConstInt<SbTYP::DATABASENAME> }, +{ u"TYP_DBNEXTSETFLD", SbxINTEGER, CPROP_, ConstInt<SbTYP::DATABASENEXTSET> }, +{ u"TYP_DBNUMSETFLD", SbxINTEGER, CPROP_, ConstInt<SbTYP::DATABASENUMBERSET> }, +{ u"TYP_DBSETNUMBERFLD", SbxINTEGER, CPROP_, ConstInt<SbTYP::DATABASESETNUMBER> }, +{ u"TYP_DDEFLD", SbxINTEGER, CPROP_, ConstInt<SbTYP::DDE> }, +{ u"TYP_DOCINFOFLD", SbxINTEGER, CPROP_, ConstInt<SbTYP::DOCUMENTINFO> }, +{ u"TYP_DOCSTATFLD", SbxINTEGER, CPROP_, ConstInt<SbTYP::DOCUMENTSTATISTICS> }, +{ u"TYP_EXTUSERFLD", SbxINTEGER, CPROP_, ConstInt<SbTYP::EXTENDEDUSER> }, +{ u"TYP_FILENAMEFLD", SbxINTEGER, CPROP_, ConstInt<SbTYP::FILENAME> }, +{ u"TYP_FIXDATEFLD", SbxINTEGER, CPROP_, ConstInt<SbTYP::FIXEDDATE> }, +{ u"TYP_FIXTIMEFLD", SbxINTEGER, CPROP_, ConstInt<SbTYP::FIXEDTIME> }, +{ u"TYP_FORMELFLD", SbxINTEGER, CPROP_, ConstInt<SbTYP::FORMEL> }, +{ u"TYP_GETFLD", SbxINTEGER, CPROP_, ConstInt<SbTYP::GET> }, +{ u"TYP_GETREFFLD", SbxINTEGER, CPROP_, ConstInt<SbTYP::GETREF> }, +{ u"TYP_GETREFPAGEFLD", SbxINTEGER, CPROP_, ConstInt<SbTYP::GETREFPAGE> }, +{ u"TYP_HIDDENPARAFLD", SbxINTEGER, CPROP_, ConstInt<SbTYP::HIDDENPARAGRAPH> }, +{ u"TYP_HIDDENTXTFLD", SbxINTEGER, CPROP_, ConstInt<SbTYP::HIDDENTEXT> }, +{ u"TYP_INPUTFLD", SbxINTEGER, CPROP_, ConstInt<SbTYP::INPUT> }, +{ u"TYP_INTERNETFLD", SbxINTEGER, CPROP_, ConstInt<SbTYP::INTERNET> }, +{ u"TYP_JUMPEDITFLD", SbxINTEGER, CPROP_, ConstInt<SbTYP::JUMPEDIT> }, +{ u"TYP_MACROFLD", SbxINTEGER, CPROP_, ConstInt<SbTYP::MACRO> }, +{ u"TYP_NEXTPAGEFLD", SbxINTEGER, CPROP_, ConstInt<SbTYP::NEXTPAGE> }, +{ u"TYP_PAGENUMBERFLD", SbxINTEGER, CPROP_, ConstInt<SbTYP::PAGENUMBER> }, +{ u"TYP_POSTITFLD", SbxINTEGER, CPROP_, ConstInt<SbTYP::POSTIT> }, +{ u"TYP_PREVPAGEFLD", SbxINTEGER, CPROP_, ConstInt<SbTYP::PREVIOUSPAGE> }, +{ u"TYP_SEQFLD", SbxINTEGER, CPROP_, ConstInt<SbTYP::SEQUENCE> }, +{ u"TYP_SETFLD", SbxINTEGER, CPROP_, ConstInt<SbTYP::SET> }, +{ u"TYP_SETINPFLD", SbxINTEGER, CPROP_, ConstInt<SbTYP::SETINPUT> }, +{ u"TYP_SETREFFLD", SbxINTEGER, CPROP_, ConstInt<SbTYP::SETREF> }, +{ u"TYP_SETREFPAGEFLD", SbxINTEGER, CPROP_, ConstInt<SbTYP::SETREFPAGE> }, +{ u"TYP_TEMPLNAMEFLD", SbxINTEGER, CPROP_, ConstInt<SbTYP::TEMPLATENAME> }, +{ u"TYP_TIMEFLD", SbxINTEGER, CPROP_, ConstInt<SbTYP::TIME> }, +{ u"TYP_USERFLD", SbxINTEGER, CPROP_, ConstInt<SbTYP::USER> }, +{ u"TYP_USRINPFLD", SbxINTEGER, CPROP_, ConstInt<SbTYP::USERINPUT> }, { u"TypeLen", SbxINTEGER, 1 | FUNCTION_, SbRtl_TypeLen }, arg(u"Var", SbxVARIANT), { u"TypeName", SbxSTRING, 1 | FUNCTION_, SbRtl_TypeName }, - arg(u"Var", SbxVARIANT), + arg(u"Varname", SbxVARIANT), { u"UBound", SbxLONG, 1 | FUNCTION_, SbRtl_UBound }, arg(u"Var", SbxVARIANT), @@ -882,17 +902,18 @@ constexpr Method aMethods[] = { arg(u"String", SbxSTRING), { u"VarType", SbxINTEGER, 1 | FUNCTION_, SbRtl_VarType }, - arg(u"Var", SbxVARIANT), - -{ u"V_EMPTY", SbxINTEGER, CPROP_, SbRtl_V_EMPTY }, -{ u"V_NULL", SbxINTEGER, CPROP_, SbRtl_V_NULL }, -{ u"V_INTEGER", SbxINTEGER, CPROP_, SbRtl_V_INTEGER }, -{ u"V_LONG", SbxINTEGER, CPROP_, SbRtl_V_LONG }, -{ u"V_SINGLE", SbxINTEGER, CPROP_, SbRtl_V_SINGLE }, -{ u"V_DOUBLE", SbxINTEGER, CPROP_, SbRtl_V_DOUBLE }, -{ u"V_CURRENCY", SbxINTEGER, CPROP_, SbRtl_V_CURRENCY }, -{ u"V_DATE", SbxINTEGER, CPROP_, SbRtl_V_DATE }, -{ u"V_STRING", SbxINTEGER, CPROP_, SbRtl_V_STRING }, + arg(u"Varname", SbxVARIANT), + +// Related to: VarType +{ u"V_EMPTY", SbxINTEGER, CPROP_, ConstInt<SbxEMPTY> }, +{ u"V_NULL", SbxINTEGER, CPROP_, ConstInt<SbxNULL> }, +{ u"V_INTEGER", SbxINTEGER, CPROP_, ConstInt<SbxINTEGER> }, +{ u"V_LONG", SbxINTEGER, CPROP_, ConstInt<SbxLONG> }, +{ u"V_SINGLE", SbxINTEGER, CPROP_, ConstInt<SbxSINGLE> }, +{ u"V_DOUBLE", SbxINTEGER, CPROP_, ConstInt<SbxDOUBLE> }, +{ u"V_CURRENCY", SbxINTEGER, CPROP_, ConstInt<SbxCURRENCY> }, +{ u"V_DATE", SbxINTEGER, CPROP_, ConstInt<SbxDATE> }, +{ u"V_STRING", SbxINTEGER, CPROP_, ConstInt<SbxSTRING> }, { u"Wait", SbxNULL, 1 | FUNCTION_, SbRtl_Wait }, arg(u"Milliseconds", SbxLONG), @@ -913,28 +934,50 @@ constexpr Method aMethods[] = { { u"Year", SbxINTEGER, 1 | FUNCTION_, SbRtl_Year }, arg(u"Date", SbxDATE), - -{ {}, SbxNULL, -1, nullptr }}; // end of the table +}; // end of the table static_assert(MethodsTableValid(aMethods)); +// building the info-structure for single elements +// if nIdx = 0, don't create anything (Std-Props!) + +SbxInfo* GetMethodInfo(std::size_t nIdx) +{ + if (!nIdx) + return nullptr; + assert(nIdx <= std::size(aMethods)); + const Method* p = &aMethods[nIdx - 1]; + SbxInfo* pInfo_ = new SbxInfo; + short nPar = p->nArgs & ARGSMASK_; + for (short i = 0; i < nPar; i++) + { + p++; + SbxFlagBits nFlags_ = static_cast<SbxFlagBits>((p->nArgs >> 8) & 0x03); + if (p->nArgs & OPT_) + nFlags_ |= SbxFlagBits::Optional; + pInfo_->AddParam(OUString(p->sName), p->eType, nFlags_); + } + return pInfo_; +} +} + SbiStdObject::SbiStdObject( const OUString& r, StarBASIC* pb ) : SbxObject( r ) { // #i92642: Remove default properties - Remove( "Name", SbxClassType::DontCare ); - Remove( "Parent", SbxClassType::DontCare ); + Remove( u"Name"_ustr, SbxClassType::DontCare ); + Remove( u"Parent"_ustr, SbxClassType::DontCare ); SetParent( pb ); - pStdFactory.reset( new SbStdFactory ); - SbxBase::AddFactory( pStdFactory.get() ); + pStdFactory.emplace(); + SbxBase::AddFactory( &*pStdFactory ); Insert( new SbStdClipboard ); } SbiStdObject::~SbiStdObject() { - SbxBase::RemoveFactory( pStdFactory.get() ); + SbxBase::RemoveFactory( &*pStdFactory ); pStdFactory.reset(); } @@ -954,7 +997,7 @@ SbxVariable* SbiStdObject::Find( const OUString& rName, SbxClassType t ) { // else search one sal_uInt16 nHash_ = SbxVariable::MakeHashCode( rName ); - const Method* p = aMethods; + auto p = std::begin(aMethods); bool bFound = false; short nIndex = 0; sal_uInt16 nSrchMask = TYPEMASK_; @@ -965,8 +1008,9 @@ SbxVariable* SbiStdObject::Find( const OUString& rName, SbxClassType t ) case SbxClassType::Object: nSrchMask = OBJECT_; break; default: break; } - while( p->nArgs != -1 ) + while (p != std::end(aMethods)) { + assert(p < std::end(aMethods)); if( ( p->nArgs & nSrchMask ) && ( p->nHash == nHash_ ) && (rName.equalsIgnoreAsciiCase(p->sName))) @@ -985,7 +1029,7 @@ SbxVariable* SbiStdObject::Find( const OUString& rName, SbxClassType t ) // No instance running => compiling a source on module level. const SbModule* pModule = GetSbData()->pCompMod; if (pModule) - bCompatibility = pModule->IsVBACompat(); + bCompatibility = pModule->IsVBASupport(); } if ((bCompatibility && (NORMONLY_ & p->nArgs)) || (!bCompatibility && (COMPATONLY_ & p->nArgs))) bFound = false; @@ -1035,14 +1079,15 @@ void SbiStdObject::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) SbxVariable* pVar = pHint->GetVar(); SbxArray* pPar_ = pVar->GetParameters(); - const sal_uInt16 nCallId = static_cast<sal_uInt16>(pVar->GetUserData()); + const std::size_t nCallId = pVar->GetUserData(); if( nCallId ) { const SfxHintId t = pHint->GetId(); if( t == SfxHintId::BasicInfoWanted ) - pVar->SetInfo( GetInfo( static_cast<short>(pVar->GetUserData()) ) ); + pVar->SetInfo(GetMethodInfo(nCallId)); else { + assert(nCallId <= std::size(aMethods)); bool bWrite = false; if( t == SfxHintId::BasicDataChanged ) bWrite = true; @@ -1063,27 +1108,4 @@ void SbiStdObject::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) SbxObject::Notify( rBC, rHint ); } -// building the info-structure for single elements -// if nIdx = 0, don't create anything (Std-Props!) - -SbxInfo* SbiStdObject::GetInfo( short nIdx ) -{ - if( !nIdx ) - return nullptr; - const Method* p = &aMethods[ --nIdx ]; - SbxInfo* pInfo_ = new SbxInfo; - short nPar = p->nArgs & ARGSMASK_; - for( short i = 0; i < nPar; i++ ) - { - p++; - SbxFlagBits nFlags_ = static_cast<SbxFlagBits>(( p->nArgs >> 8 ) & 0x03); - if( p->nArgs & OPT_ ) - { - nFlags_ |= SbxFlagBits::Optional; - } - pInfo_->AddParam(OUString(p->sName), p->eType, nFlags_); - } - return pInfo_; -} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/basic/source/runtime/stdobj1.cxx b/basic/source/runtime/stdobj1.cxx index ee7df8d7a62d..533eb2f92f24 100644 --- a/basic/source/runtime/stdobj1.cxx +++ b/basic/source/runtime/stdobj1.cxx @@ -22,23 +22,26 @@ #include <vcl/outdev.hxx> #include <sbstdobj.hxx> -#define ATTR_IMP_TYPE 1 -#define ATTR_IMP_WIDTH 2 -#define ATTR_IMP_HEIGHT 3 -#define ATTR_IMP_BOLD 4 -#define ATTR_IMP_ITALIC 5 -#define ATTR_IMP_STRIKETHROUGH 6 -#define ATTR_IMP_UNDERLINE 7 -#define ATTR_IMP_SIZE 9 -#define ATTR_IMP_NAME 10 - -#define METH_CLEAR 20 -#define METH_GETDATA 21 -#define METH_GETFORMAT 22 -#define METH_GETTEXT 23 -#define METH_SETDATA 24 -#define METH_SETTEXT 25 - +namespace { + enum UserData + { + ATTR_IMP_TYPE = 1, + ATTR_IMP_WIDTH = 2, + ATTR_IMP_HEIGHT = 3, + ATTR_IMP_BOLD = 4, + ATTR_IMP_ITALIC = 5, + ATTR_IMP_STRIKETHROUGH = 6, + ATTR_IMP_UNDERLINE = 7, + ATTR_IMP_SIZE = 9, + ATTR_IMP_NAME = 10, + METH_CLEAR = 20, + METH_GETDATA = 21, + METH_GETFORMAT = 22, + METH_GETTEXT = 23, + METH_SETDATA = 24, + METH_SETTEXT = 25 + }; +} SbStdFactory::SbStdFactory() { @@ -101,16 +104,16 @@ void SbStdPicture::PropHeight( SbxVariable* pVar, bool bWrite ) SbStdPicture::SbStdPicture() : - SbxObject( "Picture" ) + SbxObject( u"Picture"_ustr ) { // Properties - SbxVariable* p = Make( "Type", SbxClassType::Property, SbxVARIANT ); + SbxVariable* p = Make( u"Type"_ustr, SbxClassType::Property, SbxVARIANT ); p->SetFlags( SbxFlagBits::Read | SbxFlagBits::DontStore ); p->SetUserData( ATTR_IMP_TYPE ); - p = Make( "Width", SbxClassType::Property, SbxVARIANT ); + p = Make( u"Width"_ustr, SbxClassType::Property, SbxVARIANT ); p->SetFlags( SbxFlagBits::Read | SbxFlagBits::DontStore ); p->SetUserData( ATTR_IMP_WIDTH ); - p = Make( "Height", SbxClassType::Property, SbxVARIANT ); + p = Make( u"Height"_ustr, SbxClassType::Property, SbxVARIANT ); p->SetFlags( SbxFlagBits::Read | SbxFlagBits::DontStore ); p->SetUserData( ATTR_IMP_HEIGHT ); } @@ -144,6 +147,7 @@ void SbStdPicture::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) case ATTR_IMP_TYPE: PropType( pVar, bWrite ); return; case ATTR_IMP_WIDTH: PropWidth( pVar, bWrite ); return; case ATTR_IMP_HEIGHT: PropHeight( pVar, bWrite ); return; + default: break; } SbxObject::Notify( rBC, rHint ); @@ -204,7 +208,7 @@ void SbStdFont::PropName( SbxVariable* pVar, bool bWrite ) SbStdFont::SbStdFont() - : SbxObject( "Font" ) + : SbxObject( u"Font"_ustr ) , bBold(false) , bItalic(false) , bStrikeThrough(false) @@ -212,24 +216,24 @@ SbStdFont::SbStdFont() , nSize(0) { // Properties - SbxVariable* p = Make( "Bold", SbxClassType::Property, SbxVARIANT ); + SbxVariable* p = Make( u"Bold"_ustr, SbxClassType::Property, SbxVARIANT ); p->SetFlags( SbxFlagBits::ReadWrite | SbxFlagBits::DontStore ); p->SetUserData( ATTR_IMP_BOLD ); - p = Make( "Italic", SbxClassType::Property, SbxVARIANT ); + p = Make( u"Italic"_ustr, SbxClassType::Property, SbxVARIANT ); p->SetFlags( SbxFlagBits::ReadWrite | SbxFlagBits::DontStore ); p->SetUserData( ATTR_IMP_ITALIC ); - p = Make( "StrikeThrough", SbxClassType::Property, SbxVARIANT ); + p = Make( u"StrikeThrough"_ustr, SbxClassType::Property, SbxVARIANT ); p->SetFlags( SbxFlagBits::ReadWrite | SbxFlagBits::DontStore ); p->SetUserData( ATTR_IMP_STRIKETHROUGH ); - p = Make( "Underline", SbxClassType::Property, SbxVARIANT ); + p = Make( u"Underline"_ustr, SbxClassType::Property, SbxVARIANT ); p->SetFlags( SbxFlagBits::ReadWrite | SbxFlagBits::DontStore ); p->SetUserData( ATTR_IMP_UNDERLINE ); - p = Make( "Size", SbxClassType::Property, SbxVARIANT ); + p = Make( u"Size"_ustr, SbxClassType::Property, SbxVARIANT ); p->SetFlags( SbxFlagBits::ReadWrite | SbxFlagBits::DontStore ); p->SetUserData( ATTR_IMP_SIZE ); // handle name property yourself - p = Find( "Name", SbxClassType::Property ); + p = Find( u"Name"_ustr, SbxClassType::Property ); assert(p && "No Name Property"); p->SetUserData( ATTR_IMP_NAME ); } @@ -264,6 +268,7 @@ void SbStdFont::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) case ATTR_IMP_UNDERLINE: PropUnderline( pVar, bWrite ); return; case ATTR_IMP_SIZE: PropSize( pVar, bWrite ); return; case ATTR_IMP_NAME: PropName( pVar, bWrite ); return; + default: break; } SbxObject::Notify( rBC, rHint ); @@ -355,29 +360,29 @@ void SbStdClipboard::MethSetText( SbxArray const * pPar_ ) SbStdClipboard::SbStdClipboard() : - SbxObject( "Clipboard" ) + SbxObject( u"Clipboard"_ustr ) { - SbxVariable* p = Find( "Name", SbxClassType::Property ); + SbxVariable* p = Find( u"Name"_ustr, SbxClassType::Property ); assert(p && "No Name Property"); p->SetUserData( ATTR_IMP_NAME ); // register methods - p = Make( "Clear", SbxClassType::Method, SbxEMPTY ); + p = Make( u"Clear"_ustr, SbxClassType::Method, SbxEMPTY ); p->SetFlag( SbxFlagBits::DontStore ); p->SetUserData( METH_CLEAR ); - p = Make( "GetData", SbxClassType::Method, SbxEMPTY ); + p = Make( u"GetData"_ustr, SbxClassType::Method, SbxEMPTY ); p->SetFlag( SbxFlagBits::DontStore ); p->SetUserData( METH_GETDATA ); - p = Make( "GetFormat", SbxClassType::Method, SbxEMPTY ); + p = Make( u"GetFormat"_ustr, SbxClassType::Method, SbxEMPTY ); p->SetFlag( SbxFlagBits::DontStore ); p->SetUserData( METH_GETFORMAT ); - p = Make( "GetText", SbxClassType::Method, SbxEMPTY ); + p = Make( u"GetText"_ustr, SbxClassType::Method, SbxEMPTY ); p->SetFlag( SbxFlagBits::DontStore ); p->SetUserData( METH_GETTEXT ); - p = Make( "SetData", SbxClassType::Method, SbxEMPTY ); + p = Make( u"SetData"_ustr, SbxClassType::Method, SbxEMPTY ); p->SetFlag( SbxFlagBits::DontStore ); p->SetUserData( METH_SETDATA ); - p = Make( "SetText", SbxClassType::Method, SbxEMPTY ); + p = Make( u"SetText"_ustr, SbxClassType::Method, SbxEMPTY ); p->SetFlag( SbxFlagBits::DontStore ); p->SetUserData( METH_SETTEXT ); } @@ -412,6 +417,7 @@ void SbStdClipboard::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) case METH_GETTEXT: MethGetText( pVar, pPar_ ); return; case METH_SETDATA: MethSetData( pPar_ ); return; case METH_SETTEXT: MethSetText( pPar_ ); return; + default: break; } SbxObject::Notify( rBC, rHint ); |