/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
// scanning a string according to BASIC-conventions // but exponent may also be a D, so data type is SbxDOUBLE // conversion error if data type is fixed and it doesn't fit
ErrCode ImpScan( std::u16string_view rWSrc, double& nVal, SbxDataType& rType,
sal_Int32* pLen, bool* pHasNumber, bool bOnlyIntntl )
{
sal_Unicode cDecSep, cGrpSep, cDecSepAlt; if( bOnlyIntntl )
{
ImpGetIntntlSep(cDecSep, cGrpSep, cDecSepAlt); // Ensure that the decimal separator alternative is really one. if (cDecSepAlt == cDecSep)
cDecSepAlt = 0;
} else
{
cDecSep = '.';
cGrpSep = 0; // no group separator accepted in non-i18n
cDecSepAlt = 0;
}
autoconst pStart = rWSrc.begin(); auto p = pStart; bool bMinus = false;
nVal = 0;
SbxDataType eScanType = SbxSINGLE; while (p != rWSrc.end() && (*p == ' ' || *p == '\t'))
p++; if (p != rWSrc.end() && *p == '+')
p++; elseif (p != rWSrc.end() && *p == '-')
{
p++;
bMinus = true;
} #if HAVE_FEATURE_SCRIPTING if (SbiRuntime::isVBAEnabled())
{ while (p != rWSrc.end() && (*p == ' ' || *p == '\t'))
p++;
} #endif constauto pNumberStart = p; if (p != rWSrc.end()
&& (rtl::isAsciiDigit(*p)
|| ((*p == cDecSep || (cGrpSep && *p == cGrpSep) || (cDecSepAlt && *p == cDecSepAlt))
&& p + 1 != rWSrc.end() && rtl::isAsciiDigit(*(p + 1)))))
{ bool exp = false; bool decsep = false; short ndig = 0; short ncdig = 0; // number of digits after decimal point
OUStringBuffer aSearchStr("0123456789DEde" + OUStringChar(cDecSep)); if (cDecSepAlt)
aSearchStr.append(cDecSepAlt); if (cGrpSep)
aSearchStr.append(cGrpSep);
OUStringBuffer aBuf(rWSrc.end() - p); for (; p != rWSrc.end() && ImpStrChr(aSearchStr, *p); ++p)
{ if (rtl::isAsciiDigit(*p))
{
aBuf.append(*p); if (!exp)
{
ndig++; if (decsep)
ncdig++;
}
} elseif (cGrpSep && *p == cGrpSep)
{
aBuf.append(*p);
} elseif (*p == cDecSep || (cDecSepAlt && *p == cDecSepAlt))
{ if (decsep) return ERRCODE_BASIC_CONVERSION;
decsep = true;
// Use the separator that is passed to stringToDouble()
aBuf.append(cDecSep);
} else// DdEe
{ if (exp) return ERRCODE_BASIC_CONVERSION;
exp = true;
// The number is prepared unformattedly with the given number of // NK-positions. A leading minus is added if applicable. // This routine is public because it's also used by the Put-functions // in the class SbxImpSTRING.
// tdf#143575 - use rtl::math::doubleToUString to convert numbers to strings in basic
rRes = rtl::math::doubleToUString(nNum, rtl_math_StringFormat_Automatic, nPrec, cDecimalSep, true);
}
// initialize the Basic-formater help object: // get resources for predefined output // of the Format()-command, e. g. for "On/Off"
OUString aOnStrg = BasResId(STR_BASICKEY_FORMAT_ON);
OUString aOffStrg = BasResId(STR_BASICKEY_FORMAT_OFF);
OUString aYesStrg = BasResId(STR_BASICKEY_FORMAT_YES);
OUString aNoStrg = BasResId(STR_BASICKEY_FORMAT_NO);
OUString aTrueStrg = BasResId(STR_BASICKEY_FORMAT_TRUE);
OUString aFalseStrg = BasResId(STR_BASICKEY_FORMAT_FALSE);
OUString aCurrencyFormatStrg = BasResId(STR_BASICKEY_FORMAT_CURRENCY);
rAppData.pBasicFormater = std::make_unique<SbxBasicFormater>(
cComma, c1000, aOnStrg, aOffStrg, aYesStrg, aNoStrg, aTrueStrg, aFalseStrg,
aCurrencyStrg, aCurrencyFormatStrg);
} // Remark: For performance reasons there's only ONE BasicFormater- // object created and 'stored', so that the expensive resource- // loading is saved (for country-specific predefined outputs, // e. g. "On/Off") and the continuous string-creation // operations, too. // BUT: therefore this code is NOT multithreading capable!
rRes = rAppData.pBasicFormater->BasicFormat(d, rFmt);
}
// We couldn't detect a Basic-formatted number (including type characters & specific exponents). // Try generic number detection (works also for dates/times).
// Passing an index of a locale switches IsNumberFormat() to use that // locale in case the formatter wasn't default created with it.
sal_uInt32 nIndex = rpFormatter->GetStandardIndex(eLangType);
if (rpFormatter->IsNumberFormat(s, nIndex, ret)) return ret;
return {};
}
// For numeric types, takes the number directly; otherwise, tries to take string and convert it
std::optional<double> GetNumberIntl(const SbxValue& val, OUString& rStrVal,
std::shared_ptr<SvNumberFormatter>& rpFormatter, bool extendedNumberDetection)
{ switch (SbxDataType type = val.GetType())
{ case SbxCHAR: case SbxBYTE: case SbxINTEGER: case SbxUSHORT: case SbxLONG: case SbxULONG: case SbxINT: case SbxUINT: case SbxSINGLE: case SbxDOUBLE: case SbxDATE: return val.GetDouble(); case SbxBOOL: if (extendedNumberDetection) return val.GetDouble();
[[fallthrough]]; case SbxSTRING: default:
rStrVal = val.GetOUString(); return extendedNumberDetection || type == SbxSTRING
? StrToNumberIntl(rStrVal, rpFormatter)
: std::nullopt;
}
}
if (SbxBasicFormater::isBasicFormat(*pFmt))
{
BasicFormatNum(*number, *pFmt, rRes); return;
}
// pflin, It is better to use SvNumberFormatter to handle the date/time/number format. // the SvNumberFormatter output is mostly compatible with // VBA output besides the OOo-basic output #if HAVE_FEATURE_SCRIPTING // number format, use SvNumberFormatter to handle it. if (!pFormatter)
pFormatter = GetFormatter();
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.