/* -*- 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 .
*/
if (languageNode)
{
aLanguage = languageNode->getChildAt(0)->getValue(); if (aLanguage.getLength() != 2 && aLanguage.getLength() != 3)
incErrorStr( "Error: langID '%s' not 2-3 characters\n", aLanguage);
of.writeOUStringLiteralParameter("langID", aLanguage);
of.writeOUStringLiteralParameter("langDefaultName", languageNode->getChildAt(1)->getValue());
} else
incError( "No Language node."); if (countryNode)
{
OUString aCountry( countryNode->getChildAt(0)->getValue()); if (!(aCountry.isEmpty() || aCountry.getLength() == 2))
incErrorStr( "Error: countryID '%s' not empty or more than 2 characters\n", aCountry);
of.writeOUStringLiteralParameter("countryID", aCountry);
of.writeOUStringLiteralParameter("countryDefaultName", countryNode->getChildAt(1)->getValue());
} else
incError( "No Country node."); if (variantNode)
{ // If given Variant must be at least ll-Ssss and language must be 'qlt' const OUString& aVariant( variantNode->getValue()); if (!(aVariant.isEmpty() || (aVariant.getLength() >= 7 && aVariant.indexOf('-') >= 2)))
incErrorStr( "Error: invalid Variant '%s'\n", aVariant); if (!(aVariant.isEmpty() || aLanguage == "qlt"))
incErrorStrStr( "Error: Variant '%s' given but Language '%s' is not 'qlt'\n", aVariant, aLanguage);
of.writeOUStringLiteralParameter("Variant", aVariant);
} else
of.writeOUStringLiteralParameter("Variant", std::u16string_view());
of.writeAsciiString("\nstatic constexpr OUString LCInfoArray[] = {\n");
of.writeAsciiString("\tlangID,\n");
of.writeAsciiString("\tlangDefaultName,\n");
of.writeAsciiString("\tcountryID,\n");
of.writeAsciiString("\tcountryDefaultName,\n");
of.writeAsciiString("\tVariant\n");
of.writeAsciiString("};\n\n");
of.writeOUStringFunction("getLCInfo_", "std::size(LCInfoArray)", "LCInfoArray");
}
sepNode = findNode("LongDateDayOfWeekSeparator");
aLDS = sepNode->getValue();
of.writeOUStringLiteralParameter("LongDateDayOfWeekSeparator", aLDS); if (aLDS == ",")
fprintf( stderr, "Warning: %s\n", "LongDateDayOfWeekSeparator is only a comma not followed by a space. Usually this is not the case and may lead to concatenated display names like \"Wednesday,May 9, 2007\".");
sepNode = findNode("LongDateDaySeparator");
aLDS = sepNode->getValue();
of.writeOUStringLiteralParameter("LongDateDaySeparator", aLDS); if (aLDS == "," || aLDS == ".")
fprintf( stderr, "Warning: %s\n", "LongDateDaySeparator is only a comma or dot not followed by a space. Usually this is not the case and may lead to concatenated display names like \"Wednesday, May 9,2007\".");
sepNode = findNode("LongDateMonthSeparator");
aLDS = sepNode->getValue();
of.writeOUStringLiteralParameter("LongDateMonthSeparator", aLDS); if (aLDS.isEmpty())
fprintf( stderr, "Warning: %s\n", "LongDateMonthSeparator is empty. Usually this is not the case and may lead to concatenated display names like \"Wednesday, May9, 2007\".");
sepNode = findNode("LongDateYearSeparator");
aLDS = sepNode->getValue();
of.writeOUStringLiteralParameter("LongDateYearSeparator", aLDS); if (aLDS.isEmpty())
fprintf( stderr, "Warning: %s\n", "LongDateYearSeparator is empty. Usually this is not the case and may lead to concatenated display names like \"Wednesday, 2007May 9\".");
int nSavErr = nError; int nWarn = 0; if (aDateSep == aTimeSep)
incError( "DateSeparator equals TimeSeparator."); if (aDecSep == aThoSep)
incError( "DecimalSeparator equals ThousandSeparator."); if (aDecSepAlt == aThoSep)
incError( "DecimalSeparatorAlternative equals ThousandSeparator."); if (aDecSepAlt == aDecSep)
incError( "DecimalSeparatorAlternative equals DecimalSeparator, it must not be specified then."); if ( aThoSep == " " )
incError( "ThousandSeparator is an ' ' ordinary space, this should be a non-breaking space U+00A0 instead."); if (aListSep == aDecSep)
fprintf( stderr, "Warning: %s\n", "ListSeparator equals DecimalSeparator."); if (aListSep == aThoSep)
fprintf( stderr, "Warning: %s\n", "ListSeparator equals ThousandSeparator."); if (aListSep.getLength() != 1 || aListSep[0] != ';')
{
incError( "ListSeparator not ';' semicolon. Strongly recommended. Currently required.");
++nSavErr; // format codes not affected
} if (aTimeSep == aTime100Sep)
{
++nWarn;
fprintf( stderr, "Warning: %s\n", "Time100SecSeparator equals TimeSeparator, this is probably an error.");
} if (aDecSep != aTime100Sep)
{
++nWarn;
fprintf( stderr, "Warning: %s\n", "Time100SecSeparator is different from DecimalSeparator, this may be correct or not. Intended?");
} if (nSavErr != nError || nWarn)
fprintf( stderr, "Warning: %s\n", "Don't forget to adapt corresponding FormatCode elements when changing separators.");
if (aQuoteStart.toChar() <= 127 && aQuoteEnd.toChar() > 127)
fprintf( stderr, "Warning: %s\n", "QuotationStart is an ASCII character but QuotationEnd is not."); if (aQuoteEnd.toChar() <= 127 && aQuoteStart.toChar() > 127)
fprintf( stderr, "Warning: %s\n", "QuotationEnd is an ASCII character but QuotationStart is not."); if (aDoubleQuoteStart.toChar() <= 127 && aDoubleQuoteEnd.toChar() > 127)
fprintf( stderr, "Warning: %s\n", "DoubleQuotationStart is an ASCII character but DoubleQuotationEnd is not."); if (aDoubleQuoteEnd.toChar() <= 127 && aDoubleQuoteStart.toChar() > 127)
fprintf( stderr, "Warning: %s\n", "DoubleQuotationEnd is an ASCII character but DoubleQuotationStart is not."); if (aQuoteStart.toChar() <= 127 && aQuoteEnd.toChar() <= 127)
fprintf( stderr, "Warning: %s\n", "QuotationStart and QuotationEnd are both ASCII characters. Not necessarily an issue, but unusual."); if (aDoubleQuoteStart.toChar() <= 127 && aDoubleQuoteEnd.toChar() <= 127)
fprintf( stderr, "Warning: %s\n", "DoubleQuotationStart and DoubleQuotationEnd are both ASCII characters. Not necessarily an issue, but unusual."); if (aQuoteStart == aQuoteEnd)
fprintf( stderr, "Warning: %s\n", "QuotationStart equals QuotationEnd. Not necessarily an issue, but unusual."); if (aDoubleQuoteStart == aDoubleQuoteEnd)
fprintf( stderr, "Warning: %s\n", "DoubleQuotationStart equals DoubleQuotationEnd. Not necessarily an issue, but unusual."); /* TODO: should equalness of single and double quotes be an error? Would
* need to adapt quite some locales' data. */ if (aQuoteStart == aDoubleQuoteStart)
fprintf( stderr, "Warning: %s\n", "QuotationStart equals DoubleQuotationStart. Not necessarily an issue, but unusual."); if (aQuoteEnd == aDoubleQuoteEnd)
fprintf( stderr, "Warning: %s\n", "QuotationEnd equals DoubleQuotationEnd. Not necessarily an issue, but unusual."); // Known good values, exclude ASCII single (U+0027, ') and double (U+0022, ") quotes. switch (int ic = aQuoteStart.toChar())
{ case 0x2018: // LEFT SINGLE QUOTATION MARK case 0x201a: // SINGLE LOW-9 QUOTATION MARK case 0x201b: // SINGLE HIGH-REVERSED-9 QUOTATION MARK case 0x2039: // SINGLE LEFT-POINTING ANGLE QUOTATION MARK case 0x203a: // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK case 0x300c: // LEFT CORNER BRACKET (Chinese)
; break; default:
fprintf( stderr, "Warning: %s U+%04X %s\n", "QuotationStart may be wrong:", ic, OSTR( aQuoteStart));
} switch (int ic = aQuoteEnd.toChar())
{ case 0x2019: // RIGHT SINGLE QUOTATION MARK case 0x201a: // SINGLE LOW-9 QUOTATION MARK case 0x201b: // SINGLE HIGH-REVERSED-9 QUOTATION MARK case 0x2039: // SINGLE LEFT-POINTING ANGLE QUOTATION MARK case 0x203a: // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK case 0x300d: // RIGHT CORNER BRACKET (Chinese)
; break; default:
fprintf( stderr, "Warning: %s U+%04X %s\n", "QuotationEnd may be wrong:", ic, OSTR( aQuoteEnd));
} switch (int ic = aDoubleQuoteStart.toChar())
{ case 0x00ab: // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK case 0x00bb: // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK case 0x201c: // LEFT DOUBLE QUOTATION MARK case 0x201e: // DOUBLE LOW-9 QUOTATION MARK case 0x201f: // DOUBLE HIGH-REVERSED-9 QUOTATION MARK case 0x300e: // LEFT WHITE CORNER BRACKET (Chinese)
; break; default:
fprintf( stderr, "Warning: %s U+%04X %s\n", "DoubleQuotationStart may be wrong:", ic, OSTR( aDoubleQuoteStart));
} switch (int ic = aDoubleQuoteEnd.toChar())
{ case 0x00ab: // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK case 0x00bb: // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK case 0x201d: // RIGHT DOUBLE QUOTATION MARK case 0x201e: // DOUBLE LOW-9 QUOTATION MARK case 0x201f: // DOUBLE HIGH-REVERSED-9 QUOTATION MARK case 0x300f: // RIGHT WHITE CORNER BRACKET (Chinese)
; break; default:
fprintf( stderr, "Warning: %s U+%04X %s\n", "DoubleQuotationEnd may be wrong:", ic, OSTR( aDoubleQuoteEnd));
}
OUString str;
OUString strFrom( getAttr().getValueByName("replaceFrom")); if (useLocale.isEmpty())
{
of.writeParameter("replaceFrom", strFrom, mnSection);
}
str = getAttr().getValueByName("replaceTo"); if (!strFrom.isEmpty() && str.isEmpty())
incErrorStr("replaceFrom=\"%s\" replaceTo=\"\" is empty replacement.\n", strFrom); // Locale data generator inserts FFFF for LangID, we need to adapt that. if (str.endsWithIgnoreAsciiCase( "-FFFF]"))
incErrorStr("replaceTo=\"%s\" needs FFFF to be adapted to the real LangID value.\n", str);
of.writeParameter("replaceTo", str, mnSection); // Remember the replaceTo value for "[CURRENCY]" to check format codes. if ( strFrom == "[CURRENCY]" )
sTheCurrencyReplaceTo = str; // Remember the currency symbol if present. if (str.startsWith( "[$" ))
{
sal_Int32 nHyphen = str.indexOf( '-'); if (nHyphen >= 3)
{
sTheCompatibleCurrency = str.copy( 2, nHyphen - 2);
}
}
if (!useLocale.isEmpty())
{ if (!strFrom.isEmpty() && strFrom != "[CURRENCY]") //???
{
incErrorStrStr( "Error: non-empty replaceFrom=\"%s\" with non-empty ref=\"%s\".",
strFrom, useLocale);
}
useLocale = useLocale.replace( '-', '_'); switch (mnSection)
{ case 0:
of.writeOUStringRefFunction("getAllFormats0_", useLocale, "replaceTo0");
of.writeOUStringRefFunction("getDateAcceptancePatterns_", useLocale); break; case 1:
of.writeOUStringRefFunction("getAllFormats1_", useLocale, "replaceTo1"); break;
}
++mnSection; return;
}
aFormatIndex = currNodeAttr.getValueByName("formatindex");
sal_Int16 formatindex = static_cast<sal_Int16>(aFormatIndex.toInt32()); // Ensure the new reserved range is not used anymore, free usage start // was up'ed from 50 to 60 (and more later). if (i18npool::nStopPredefinedFormatIndex <= formatindex && formatindex < i18npool::nFirstFreeFormatIndex)
{
incErrorInt( "Error: Reserved formatindex=\"%d\" in FormatElement.\n", formatindex);
bShowNextFreeFormatIndex = true;
} if (!aFormatIndexSet.insert( formatindex).second)
{
incErrorInt( "Error: Duplicated formatindex=\"%d\" in FormatElement.\n", formatindex);
bShowNextFreeFormatIndex = true;
}
of.writeOUStringLiteralIntParameter("Formatindex", formatCount, formatindex);
// Ensure only one default per usage and type. if (bDefault)
{
OUString aKey( aUsage + "," + aType); if (!aDefaultsSet.insert( aKey).second)
{
OUString aStr = "Duplicated default for usage=\"" + aUsage + "\" type=\"" + aType + "\": formatindex=\"" + aFormatIndex + "\".";
incError( aStr);
}
}
const LocaleNode * n = currNode -> findNode("FormatCode"); if (n)
{
of.writeOUStringLiteralParameter("FormatCode", n->getValue(), formatCount); // Check separator usage for some FormatCode elements. const LocaleNode* pCtype = nullptr; switch (formatindex)
{ case cssi::NumberFormatIndex::DATE_SYS_DDMMYYYY :
sTheDateEditFormat = n->getValue(); break; case cssi::NumberFormatIndex::NUMBER_1000DEC2 : // #,##0.00 case cssi::NumberFormatIndex::TIME_MMSS00 : // MM:SS.00 case cssi::NumberFormatIndex::TIME_HH_MMSS00 : // [HH]:MM:SS.00
{ const LocaleNode* pRoot = getRoot(); if (!pRoot)
incError( "No root for FormatCode."); else
{
pCtype = pRoot->findNode( "LC_CTYPE"); if (!pCtype)
incError( "No LC_CTYPE found for FormatCode."); else
{
OUString aRef( pCtype->getAttr().getValueByName("ref")); if (!aRef.isEmpty())
{
aRef = aRef.replace( '-', '_'); if (!bCtypeIsRef)
fprintf( stderr, "Warning: Can't check separators used in FormatCode due to LC_CTYPE ref=\"%s\".\n" "If these two locales use identical format codes, you should consider to use the ref= mechanism also for the LC_FORMAT element, together with replaceFrom= and replaceTo= for the currency.\n",
OSTR( aRef));
bCtypeIsRef = true;
pCtype = nullptr;
}
}
}
} break; case cssi::NumberFormatIndex::CURRENCY_1000DEC2 : // Remember the currency symbol if present.
{ if (sTheCompatibleCurrency.isEmpty())
{
sal_Int32 nStart = n->getValue().indexOf("[$"); if (nStart >= 0)
{ const OUString& aCode( n->getValue());
sal_Int32 nHyphen = aCode.indexOf( '-', nStart); if (nHyphen >= nStart + 3)
sTheCompatibleCurrency = aCode.copy( nStart + 2, nHyphen - nStart - 2);
}
}
}
[[fallthrough]]; case cssi::NumberFormatIndex::CURRENCY_1000INT : case cssi::NumberFormatIndex::CURRENCY_1000INT_RED : case cssi::NumberFormatIndex::CURRENCY_1000DEC2_RED : case cssi::NumberFormatIndex::CURRENCY_1000DEC2_CCC : case cssi::NumberFormatIndex::CURRENCY_1000DEC2_DASHED : // Currency formats should be something like [C]###0;-[C]###0 // and not parenthesized [C]###0;([C]###0) if not en_US. if (strcmp( of.getLocale(), "en_US") != 0)
{ const OUString& aCode( n->getValue()); if (aCode.indexOf( "0)" ) > 0 || aCode.indexOf( "-)" ) > 0 ||
aCode.indexOf( " )" ) > 0 || aCode.indexOf( "])" ) > 0)
fprintf( stderr, "Warning: FormatCode formatindex=\"%d\" for currency uses parentheses for negative amounts, which probably is not correct for locales not based on en_US.\n", formatindex);
} // Check if we have replaceTo for "[CURRENCY]" placeholder. if (sTheCurrencyReplaceTo.isEmpty())
{ const OUString& aCode( n->getValue()); if (aCode.indexOf( "[CURRENCY]" ) >= 0)
incErrorInt( "Error: [CURRENCY] replaceTo not found for formatindex=\"%d\".\n", formatindex);
} break; default: if (aUsage == "SCIENTIFIC_NUMBER")
{ // Check for presence of ##0.00E+00 const OUString& aCode( n->getValue()); // Simple check without decimal separator (assumed to // be one UTF-16 character). May be prefixed with // [NatNum1] or other tags.
sal_Int32 nInt = aCode.indexOf("##0");
sal_Int32 nDec = (nInt < 0 ? -1 : aCode.indexOf("00E+00", nInt)); if (nInt >= 0 && nDec == nInt+4)
bHaveEngineering = true;
} break;
} if (pCtype)
{ int nSavErr = nError; const OUString& aCode( n->getValue()); if (formatindex == cssi::NumberFormatIndex::NUMBER_1000DEC2)
{
sal_Int32 nDec = -1;
sal_Int32 nGrp = -1; const LocaleNode* pSep = pCtype->findNode( "DecimalSeparator"); if (!pSep)
incError( "No DecimalSeparator found for FormatCode."); else
{
nDec = aCode.indexOf( pSep->getValue()); if (nDec < 0)
incErrorInt( "Error: DecimalSeparator not present in FormatCode formatindex=\"%d\".\n",
formatindex);
}
pSep = pCtype->findNode( "ThousandSeparator"); if (!pSep)
incError( "No ThousandSeparator found for FormatCode."); else
{
nGrp = aCode.indexOf( pSep->getValue()); if (nGrp < 0)
incErrorInt( "Error: ThousandSeparator not present in FormatCode formatindex=\"%d\".\n",
formatindex);
} if (nDec >= 0 && nGrp >= 0 && nDec <= nGrp)
incErrorInt( "Error: Ordering of ThousandSeparator and DecimalSeparator not correct in formatindex=\"%d\".\n",
formatindex);
} if (formatindex == cssi::NumberFormatIndex::TIME_MMSS00 ||
formatindex == cssi::NumberFormatIndex::TIME_HH_MMSS00)
{
sal_Int32 nTime = -1;
sal_Int32 n100s = -1; const LocaleNode* pSep = pCtype->findNode( "TimeSeparator"); if (!pSep)
incError( "No TimeSeparator found for FormatCode."); else
{
nTime = aCode.indexOf( pSep->getValue()); if (nTime < 0)
incErrorInt( "Error: TimeSeparator not present in FormatCode formatindex=\"%d\".\n",
formatindex);
}
pSep = pCtype->findNode( "Time100SecSeparator"); if (!pSep)
incError( "No Time100SecSeparator found for FormatCode."); else
{
n100s = aCode.indexOf( pSep->getValue()); if (n100s < 0)
incErrorInt( "Error: Time100SecSeparator not present in FormatCode formatindex=\"%d\".\n",
formatindex);
n100s = aCode.indexOf( Concat2View(pSep->getValue() + "00")); if (n100s < 0)
incErrorInt( "Error: Time100SecSeparator+00 not present in FormatCode formatindex=\"%d\".\n",
formatindex);
} if (n100s >= 0 && nTime >= 0 && n100s <= nTime)
incErrorInt( "Error: Ordering of Time100SecSeparator and TimeSeparator not correct in formatindex=\"%d\".\n",
formatindex);
} if (nSavErr != nError)
fprintf( stderr, "Warning: formatindex=\"%d\",\"%d\",\"%d\" are the only FormatCode elements checked for separator usage, there may be others that have errors.\n", int(cssi::NumberFormatIndex::NUMBER_1000DEC2), int(cssi::NumberFormatIndex::TIME_MMSS00), int(cssi::NumberFormatIndex::TIME_HH_MMSS00));
}
} else
incError( "No FormatCode in FormatElement.");
n = currNode -> findNode("DefaultName"); if (n)
of.writeOUStringLiteralParameter("FormatDefaultName", n->getValue(), formatCount); else
of.writeOUStringLiteralParameter("FormatDefaultName", std::u16string_view(), formatCount);
}
if (bShowNextFreeFormatIndex)
{
sal_Int16 nNext = i18npool::nFirstFreeFormatIndex; auto it = aFormatIndexSet.find( nNext); if (it != aFormatIndexSet.end())
{ // nFirstFreeFormatIndex already used, find next free including gaps. do
{
++nNext;
} while (++it != aFormatIndexSet.end() && *it == nNext);
}
fprintf( stderr, "Hint: Next free formatindex is %d.\n", static_cast<int>(nNext));
}
// Check presence of all required format codes only in first section // LC_FORMAT, not in optional LC_FORMAT_1 if (mnSection == 0)
{ // At least one abbreviated date acceptance pattern must be present. if (theDateAcceptancePatterns.empty())
incError( "No DateAcceptancePattern present.\n"); else
{ bool bHaveAbbr = false; for (autoconst& elem : theDateAcceptancePatterns)
{ if (elem.indexOf('D') > -1 && elem.indexOf('M') > -1 && elem.indexOf('Y') <= -1)
{
bHaveAbbr = true; break;
}
} if (!bHaveAbbr)
incError( "No abbreviated DateAcceptancePattern present. For example M/D or D.M.\n");
}
// 0..9 MUST be present, 10,11 MUST NOT be present, 12..47 MUST be // present, 48,49 MUST NOT be present, 50 MUST be present.
ValueSet::const_iterator aIter( aFormatIndexSet.begin()); for (sal_Int16 nNext = cssi::NumberFormatIndex::NUMBER_START;
nNext < i18npool::nStopPredefinedFormatIndex; ++nNext)
{
sal_Int16 nHere = ::std::min( (aIter != aFormatIndexSet.end() ? *aIter :
i18npool::nStopPredefinedFormatIndex),
i18npool::nStopPredefinedFormatIndex); if (aIter != aFormatIndexSet.end()) ++aIter; for ( ; nNext < nHere; ++nNext)
{ switch (nNext)
{ case cssi::NumberFormatIndex::FRACTION_1 : case cssi::NumberFormatIndex::FRACTION_2 : case cssi::NumberFormatIndex::BOOLEAN : case cssi::NumberFormatIndex::TEXT : // generated internally break; default:
incErrorInt( "Error: FormatElement formatindex=\"%d\" not present.\n", nNext);
}
} switch (nHere)
{ case cssi::NumberFormatIndex::FRACTION_1 :
incErrorInt( "Error: FormatElement formatindex=\"%d\" reserved for internal ``# ?/?''.\n", nNext); break; case cssi::NumberFormatIndex::FRACTION_2 :
incErrorInt( "Error: FormatElement formatindex=\"%d\" reserved for internal ``# ?\?/?\?''.\n", nNext); break; case cssi::NumberFormatIndex::BOOLEAN :
incErrorInt( "Error: FormatElement formatindex=\"%d\" reserved for internal ``BOOLEAN''.\n", nNext); break; case cssi::NumberFormatIndex::TEXT :
incErrorInt( "Error: FormatElement formatindex=\"%d\" reserved for internal ``@'' (TEXT).\n", nNext); break; default:
; // nothing
}
}
if (!bHaveEngineering)
incError("Engineering notation format not present, e.g. ##0.00E+00 or ##0,00E+00 for usage=\"SCIENTIFIC_NUMBER\"\n");
}
// Rudimentary check if a pattern interferes with decimal number. // But only if not inherited in which case we don't have aDecSep here. if (!aDecSep.isEmpty())
{
sal_uInt32 cDecSep = aDecSep.iterateCodePoints( &o3tl::temporary(sal_Int32(0))); for (autoconst& elem : theDateAcceptancePatterns)
{ if (elem.getLength() == (cDecSep <= 0xffff ? 3 : 4))
{ if (elem.iterateCodePoints( &o3tl::temporary(sal_Int32(1))) == cDecSep)
{
++nError;
fprintf( stderr, "Error: Date acceptance pattern '%s' matches decimal number '#%s#'\n",
OSTR(elem), OSTR( aDecSep));
}
}
}
}
for (sal_Int16 i = 0; i < nbOfDateAcceptancePatterns; ++i)
{
of.writeOUStringLiteralParameter("DateAcceptancePattern", theDateAcceptancePatterns[i], i);
}
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.