formula/source/core/resource/core_resource.src | 28 +++ i18nlangtag/source/languagetag/languagetag.cxx | 15 +- include/formula/compiler.hrc | 6 include/formula/opcode.hxx | 4 sc/inc/helpids.h | 4 sc/qa/unit/data/xlsx/functions-excel-2010.xlsx |binary sc/qa/unit/subsequent_filters-test.cxx | 107 ++++++++++++-- sc/qa/unit/ucalc.cxx | 4 sc/source/core/inc/interpre.hxx | 2 sc/source/core/tool/interpr3.cxx | 71 ++++++++- sc/source/core/tool/interpr4.cxx | 10 - sc/source/filter/excel/xlformula.cxx | 48 +++--- sc/source/filter/oox/formulabase.cxx | 6 sc/source/ui/src/scfuncs.src | 184 +++++++++++++++++++++++++ udkapi/com/sun/star/lang/Locale.idl | 49 ++++-- 15 files changed, 468 insertions(+), 70 deletions(-)
New commits: commit 0d94f14ba641752401f6782f75c015f3f031f679 Author: Eike Rathke <er...@redhat.com> Date: Fri Nov 22 16:27:06 2013 +0100 more tests for new Excel 2010 functions, fdo#70798 Change-Id: If996e57a616adfb21f09463ac305e64c4e2fa4cc (cherry picked from commit 52999789258aa7cfde8d01ff7e8a03a0f53278db) diff --git a/sc/qa/unit/data/xlsx/functions-excel-2010.xlsx b/sc/qa/unit/data/xlsx/functions-excel-2010.xlsx index 36756ac..48f5a7f 100755 Binary files a/sc/qa/unit/data/xlsx/functions-excel-2010.xlsx and b/sc/qa/unit/data/xlsx/functions-excel-2010.xlsx differ diff --git a/sc/qa/unit/subsequent_filters-test.cxx b/sc/qa/unit/subsequent_filters-test.cxx index 100684b..581734b 100644 --- a/sc/qa/unit/subsequent_filters-test.cxx +++ b/sc/qa/unit/subsequent_filters-test.cxx @@ -380,20 +380,101 @@ void ScFiltersTest::testFunctionsExcel2010() ScDocument* pDoc = xDocSh->GetDocument(); pDoc->CalcAll(); // perform hard re-calculation. - // B2:B6 and B8:B10 should all be formula cells, and shouldn't have errors. - CPPUNIT_ASSERT_MESSAGE("Expected a formula cell without error.", isFormulaWithoutError(*pDoc, ScAddress(1,1,0))); - CPPUNIT_ASSERT_MESSAGE("Expected a formula cell without error.", isFormulaWithoutError(*pDoc, ScAddress(1,2,0))); - CPPUNIT_ASSERT_MESSAGE("Expected a formula cell without error.", isFormulaWithoutError(*pDoc, ScAddress(1,3,0))); - CPPUNIT_ASSERT_MESSAGE("Expected a formula cell without error.", isFormulaWithoutError(*pDoc, ScAddress(1,4,0))); - CPPUNIT_ASSERT_MESSAGE("Expected a formula cell without error.", isFormulaWithoutError(*pDoc, ScAddress(1,5,0))); - // Skip B7. - -#if 0 //F.DIST.RT not yet supported in the core. - CPPUNIT_ASSERT_MESSAGE("Expected a formula cell without error.", isFormulaWithoutError(*pDoc, ScAddress(1,7,0))); -#endif + // Which test rows to evaluate, 1-based as in UI to ease maintenance. + struct + { + SCROW nRow; + bool bEvaluate; + } aTests[] = { + { 2, false }, + { 3, true }, + { 4, true }, + { 5, true }, + { 6, true }, + { 7, true }, + { 8, true }, + { 9, false }, + { 10, false }, + { 11, true }, + { 12, true }, + { 13, true }, + { 14, true }, + { 15, true }, + { 16, true }, + { 17, true }, + { 18, true }, + { 19, true }, + { 20, false }, + { 21, false }, + { 22, true }, + { 23, true }, + { 24, true }, + { 25, true }, + { 26, true }, + { 27, true }, + { 28, true }, + { 29, true }, + { 30, false }, + { 31, false }, + { 32, false }, + { 33, false }, + { 34, true }, + { 35, true }, + { 36, false }, + { 37, false }, + { 38, false }, + { 39, false }, + { 40, false }, + { 41, false }, + { 42, false }, + { 43, false }, + { 44, false }, + { 45, false }, + { 46, false }, + { 47, false }, + { 48, false }, + { 49, false }, + { 50, false }, + { 51, false }, + { 52, false }, + { 53, false }, + { 54, true }, + { 55, true }, + { 56, false }, + { 57, false }, + { 58, false }, + { 59, false }, + { 60, true }, + { 61, true }, + { 62, false }, + { 63, false }, + { 64, false }, + { 65, false }, + { 66, false }, + { 67, false }, + { 68, true }, + { 69, true }, + { 70, true }, + { 71, true }, + { 72, false }, + { 73, false } + }; - CPPUNIT_ASSERT_MESSAGE("Expected a formula cell without error.", isFormulaWithoutError(*pDoc, ScAddress(1,8,0))); - CPPUNIT_ASSERT_MESSAGE("Expected a formula cell without error.", isFormulaWithoutError(*pDoc, ScAddress(1,9,0))); + for (size_t i=0; i < SAL_N_ELEMENTS(aTests); ++i) + { + if (aTests[i].bEvaluate) + { + // Column A is description, B is formula, C is Excel result, D is + // comparison. + SCROW nRow = aTests[i].nRow - 1; // 0-based + CPPUNIT_ASSERT_MESSAGE( OString( "Expected a formula cell without error at row " + + OString::number( aTests[i].nRow)).getStr(), + isFormulaWithoutError( *pDoc, ScAddress( 1, nRow, 0))); + CPPUNIT_ASSERT_MESSAGE( OString( "Expected a TRUE value at row " + + OString::number( aTests[i].nRow)).getStr(), + 0 != pDoc->GetValue( ScAddress( 3, nRow, 0))); + } + } xDocSh->DoClose(); } commit dec38b9b514e256354297073b2bf556f4a2c3c38 Author: Winfried Donkers <winfrieddonk...@libreoffice.org> Date: Thu Nov 21 11:16:43 2013 +0100 fdo#71722 add Excel 2010 functions EXPON.DIST, HYPGEOM.DIST, POISSON.DIST, WEIBULL.DIST Change-Id: Ib9f648739ec0af90cdf2f576c7f548a6acb7b4a6 Reviewed-on: https://gerrit.libreoffice.org/6748 Reviewed-by: Eike Rathke <er...@redhat.com> Tested-by: Eike Rathke <er...@redhat.com> (cherry picked from commit e434c1ce0557454ef4cdd98435c5c0b1d5181bcf) diff --git a/formula/source/core/resource/core_resource.src b/formula/source/core/resource/core_resource.src index 609928b..afb1d15 100644 --- a/formula/source/core/resource/core_resource.src +++ b/formula/source/core/resource/core_resource.src @@ -195,9 +195,11 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH_ODFF String SC_OPCODE_B { Text = "BINOM.DIST.RANGE" ; }; String SC_OPCODE_NORM_DIST { Text = "NORMDIST" ; }; String SC_OPCODE_EXP_DIST { Text = "EXPONDIST" ; }; + String SC_OPCODE_EXP_DIST_MS { Text = "COM.MICROSOFT.EXPON.DIST" ; }; String SC_OPCODE_BINOM_DIST { Text = "BINOMDIST" ; }; String SC_OPCODE_BINOM_DIST_MS { Text = "COM.MICROSOFT.BINOM.DIST" ; }; String SC_OPCODE_POISSON_DIST { Text = "POISSON" ; }; + String SC_OPCODE_POISSON_DIST_MS { Text = "COM.MICROSOFT.POISSON.DIST" ; }; String SC_OPCODE_KOMBIN { Text = "COMBIN" ; }; String SC_OPCODE_KOMBIN_2 { Text = "COMBINA" ; }; String SC_OPCODE_VARIATIONEN { Text = "PERMUT" ; }; @@ -281,6 +283,7 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH_ODFF String SC_OPCODE_MATRIX_UNIT { Text = "MUNIT" ; }; String SC_OPCODE_BACK_SOLVER { Text = "GOALSEEK" ; }; String SC_OPCODE_HYP_GEOM_DIST { Text = "HYPGEOMDIST" ; }; + String SC_OPCODE_HYP_GEOM_DIST_MS { Text = "COM.MICROSOFT.HYPGEOM.DIST" ; }; String SC_OPCODE_LOG_NORM_DIST { Text = "LOGNORMDIST" ; }; String SC_OPCODE_T_DIST { Text = "LEGACY.TDIST" ; }; String SC_OPCODE_F_DIST { Text = "LEGACY.FDIST" ; }; @@ -289,6 +292,7 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH_ODFF String SC_OPCODE_CHI_DIST { Text = "LEGACY.CHIDIST" ; }; String SC_OPCODE_CHI_DIST_MS { Text = "COM.MICROSOFT.CHISQ.DIST.RT" ; }; String SC_OPCODE_WEIBULL { Text = "WEIBULL" ; }; + String SC_OPCODE_WEIBULL_MS { Text = "COM.MICROSOFT.WEIBULL.DIST" ; }; String SC_OPCODE_NEG_BINOM_VERT { Text = "NEGBINOMDIST" ; }; String SC_OPCODE_KRIT_BINOM { Text = "CRITBINOM" ; }; String SC_OPCODE_BINOM_INV { Text = "COM.MICROSOFT.BINOM.INV" ; }; @@ -563,9 +567,11 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH_OOXML String SC_OPCODE_B { Text = "B" ; }; String SC_OPCODE_NORM_DIST { Text = "NORMDIST" ; }; String SC_OPCODE_EXP_DIST { Text = "EXPONDIST" ; }; + String SC_OPCODE_EXP_DIST_MS { Text = "_xlfn.EXPON.DIST" ; }; String SC_OPCODE_BINOM_DIST { Text = "BINOMDIST" ; }; String SC_OPCODE_BINOM_DIST_MS { Text = "_xlfn.BINOM.DIST" ; }; String SC_OPCODE_POISSON_DIST { Text = "POISSON" ; }; + String SC_OPCODE_POISSON_DIST_MS { Text = "_xlfn.POISSON.DIST" ; }; String SC_OPCODE_KOMBIN { Text = "COMBIN" ; }; String SC_OPCODE_KOMBIN_2 { Text = "_xlfn.COMBINA" ; }; String SC_OPCODE_VARIATIONEN { Text = "PERMUT" ; }; @@ -649,6 +655,7 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH_OOXML String SC_OPCODE_MATRIX_UNIT { Text = "_xlfn.MUNIT" ; }; String SC_OPCODE_BACK_SOLVER { Text = "GOALSEEK" ; }; String SC_OPCODE_HYP_GEOM_DIST { Text = "HYPGEOMDIST" ; }; + String SC_OPCODE_HYP_GEOM_DIST_MS { Text = "_xlfn.HYPGEOM.DIST" ; }; String SC_OPCODE_LOG_NORM_DIST { Text = "LOGNORMDIST" ; }; String SC_OPCODE_T_DIST { Text = "TDIST" ; }; String SC_OPCODE_F_DIST { Text = "FDIST" ; }; @@ -657,6 +664,7 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH_OOXML String SC_OPCODE_CHI_DIST { Text = "CHIDIST" ; }; String SC_OPCODE_CHI_DIST_MS { Text = "_xlfn.CHISQ.DIST.RT" ; }; String SC_OPCODE_WEIBULL { Text = "WEIBULL" ; }; + String SC_OPCODE_WEIBULL_MS { Text = "_xlfn.WEIBULL.DIST" ; }; String SC_OPCODE_NEG_BINOM_VERT { Text = "NEGBINOMDIST" ; }; String SC_OPCODE_KRIT_BINOM { Text = "CRITBINOM" ; }; String SC_OPCODE_BINOM_INV { Text = "_xlfn.BINOM.INV" ; }; @@ -933,9 +941,11 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH String SC_OPCODE_B { Text = "B" ; }; String SC_OPCODE_NORM_DIST { Text = "NORMDIST" ; }; String SC_OPCODE_EXP_DIST { Text = "EXPONDIST" ; }; + String SC_OPCODE_EXP_DIST_MS { Text = "EXPON.DIST" ; }; String SC_OPCODE_BINOM_DIST { Text = "BINOMDIST" ; }; String SC_OPCODE_BINOM_DIST_MS { Text = "BINOM.DIST" ; }; String SC_OPCODE_POISSON_DIST { Text = "POISSON" ; }; + String SC_OPCODE_POISSON_DIST_MS { Text = "POISSON.DIST" ; }; String SC_OPCODE_KOMBIN { Text = "COMBIN" ; }; String SC_OPCODE_KOMBIN_2 { Text = "COMBINA" ; }; String SC_OPCODE_VARIATIONEN { Text = "PERMUT" ; }; @@ -1019,6 +1029,7 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH String SC_OPCODE_MATRIX_UNIT { Text = "MUNIT" ; }; String SC_OPCODE_BACK_SOLVER { Text = "GOALSEEK" ; }; String SC_OPCODE_HYP_GEOM_DIST { Text = "HYPGEOMDIST" ; }; + String SC_OPCODE_HYP_GEOM_DIST_MS { Text = "HYPGEOM.DIST" ; }; String SC_OPCODE_LOG_NORM_DIST { Text = "LOGNORMDIST" ; }; String SC_OPCODE_T_DIST { Text = "TDIST" ; }; String SC_OPCODE_F_DIST { Text = "FDIST" ; }; @@ -1027,6 +1038,7 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH String SC_OPCODE_CHI_DIST { Text = "CHIDIST" ; }; String SC_OPCODE_CHI_DIST_MS { Text = "CHISQ.DIST.RT" ; }; String SC_OPCODE_WEIBULL { Text = "WEIBULL" ; }; + String SC_OPCODE_WEIBULL_MS { Text = "WEIBULL.DIST" ; }; String SC_OPCODE_NEG_BINOM_VERT { Text = "NEGBINOMDIST" ; }; String SC_OPCODE_KRIT_BINOM { Text = "CRITBINOM" ; }; String SC_OPCODE_BINOM_INV { Text = "BINOM.INV" ; }; @@ -1743,6 +1755,10 @@ Resource RID_STRLIST_FUNCTION_NAMES { Text [ en-US ] = "EXPONDIST" ; }; + String SC_OPCODE_EXP_DIST_MS + { + Text [ en-US ] = "EXPON.DIST" ; + }; String SC_OPCODE_BINOM_DIST { Text [ en-US ] = "BINOMDIST" ; @@ -1755,6 +1771,10 @@ Resource RID_STRLIST_FUNCTION_NAMES { Text [ en-US ] = "POISSON" ; }; + String SC_OPCODE_POISSON_DIST_MS + { + Text [ en-US ] = "POISSON.DIST" ; + }; String SC_OPCODE_KOMBIN { Text [ en-US ] = "COMBIN" ; @@ -2088,6 +2108,10 @@ Resource RID_STRLIST_FUNCTION_NAMES { Text [ en-US ] = "HYPGEOMDIST" ; }; + String SC_OPCODE_HYP_GEOM_DIST_MS + { + Text [ en-US ] = "HYPGEOM.DIST" ; + }; String SC_OPCODE_LOG_NORM_DIST { Text [ en-US ] = "LOGNORMDIST" ; @@ -2120,6 +2144,10 @@ Resource RID_STRLIST_FUNCTION_NAMES { Text [ en-US ] = "WEIBULL" ; }; + String SC_OPCODE_WEIBULL_MS + { + Text [ en-US ] = "WEIBULL.DIST" ; + }; String SC_OPCODE_NEG_BINOM_VERT { Text [ en-US ] = "NEGBINOMDIST" ; diff --git a/include/formula/compiler.hrc b/include/formula/compiler.hrc index 4f2f4e6..9bda945 100644 --- a/include/formula/compiler.hrc +++ b/include/formula/compiler.hrc @@ -430,8 +430,12 @@ #define SC_OPCODE_F_INV_LT 432 #define SC_OPCODE_F_INV_RT 433 #define SC_OPCODE_F_TEST_MS 434 +#define SC_OPCODE_EXP_DIST_MS 435 +#define SC_OPCODE_HYP_GEOM_DIST_MS 436 +#define SC_OPCODE_POISSON_DIST_MS 437 +#define SC_OPCODE_WEIBULL_MS 438 -#define SC_OPCODE_STOP_2_PAR 435 /* last function with two or more parameters' OpCode + 1 */ +#define SC_OPCODE_STOP_2_PAR 439 /* last function with two or more parameters' OpCode + 1 */ #define SC_OPCODE_STOP_FUNCTION SC_OPCODE_STOP_2_PAR /* last function's OpCode + 1 */ #define SC_OPCODE_LAST_OPCODE_ID (SC_OPCODE_STOP_FUNCTION - 1) /* last OpCode */ diff --git a/include/formula/opcode.hxx b/include/formula/opcode.hxx index b5953f7..58f3d41 100644 --- a/include/formula/opcode.hxx +++ b/include/formula/opcode.hxx @@ -229,10 +229,12 @@ enum OpCodeEnum ocB = SC_OPCODE_B, ocNormDist = SC_OPCODE_NORM_DIST, ocExpDist = SC_OPCODE_EXP_DIST, + ocExpDist_MS = SC_OPCODE_EXP_DIST_MS, ocBinomDist = SC_OPCODE_BINOM_DIST, ocBinomDist_MS = SC_OPCODE_BINOM_DIST_MS, ocBinomInv = SC_OPCODE_BINOM_INV, ocPoissonDist = SC_OPCODE_POISSON_DIST, + ocPoissonDist_MS = SC_OPCODE_POISSON_DIST_MS, ocKombin = SC_OPCODE_KOMBIN, ocKombin2 = SC_OPCODE_KOMBIN_2, ocVariationen = SC_OPCODE_VARIATIONEN, @@ -323,6 +325,7 @@ enum OpCodeEnum ocBackSolver = SC_OPCODE_BACK_SOLVER, // Statistical functions ocHypGeomDist = SC_OPCODE_HYP_GEOM_DIST, + ocHypGeomDist_MS = SC_OPCODE_HYP_GEOM_DIST_MS, ocLogNormDist = SC_OPCODE_LOG_NORM_DIST, ocTDist = SC_OPCODE_T_DIST, ocFDist = SC_OPCODE_F_DIST, @@ -335,6 +338,7 @@ enum OpCodeEnum ocChiSqInv = SC_OPCODE_CHISQ_INV, ocChiSqInv_MS = SC_OPCODE_CHISQ_INV_MS, ocWeibull = SC_OPCODE_WEIBULL, + ocWeibull_MS = SC_OPCODE_WEIBULL_MS, ocNegBinomVert = SC_OPCODE_NEG_BINOM_VERT, ocKritBinom = SC_OPCODE_KRIT_BINOM, ocKurt = SC_OPCODE_KURT, diff --git a/sc/inc/helpids.h b/sc/inc/helpids.h index 5547551..e1c2dac 100644 --- a/sc/inc/helpids.h +++ b/sc/inc/helpids.h @@ -700,5 +700,9 @@ #define HID_FUNC_F_INV_LT "SC_HID_FUNC_F_INV_LT" #define HID_FUNC_F_INV_RT "SC_HID_FUNC_F_INV_RT" #define HID_FUNC_F_TEST_MS "SC_HID_FUNC_F_TEST_MS" +#define HID_FUNC_EXP_DIST_MS "SC_HID_FUNC_EXP_DIST_MS" +#define HID_FUNC_HYP_GEOM_DIST_MS "SC_HID_FUNC_HYP_GEOM_DIST_MS" +#define HID_FUNC_POISSON_DIST_MS "SC_HID_FUNC_POISSON_DIST_MS" +#define HID_FUNC_WEIBULL_DIST_MS "SC_HID_FUNC_WEIBULL_DIST_MS" /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx index b48f4f2..681283c 100644 --- a/sc/qa/unit/ucalc.cxx +++ b/sc/qa/unit/ucalc.cxx @@ -2388,6 +2388,7 @@ void Test::testFunctionLists() "COVARIANCE.S", "CRITBINOM", "DEVSQ", + "EXPON.DIST", "EXPONDIST", "F.DIST", "F.DIST.RT", @@ -2407,6 +2408,7 @@ void Test::testFunctionLists() "GAUSS", "GEOMEAN", "HARMEAN", + "HYPGEOM.DIST", "HYPGEOMDIST", "INTERCEPT", "KURT", @@ -2431,6 +2433,7 @@ void Test::testFunctionLists() "PERMUTATIONA", "PHI", "POISSON", + "POISSON.DIST", "PROB", "QUARTILE", "RANK", @@ -2458,6 +2461,7 @@ void Test::testFunctionLists() "VARP", "VARPA", "WEIBULL", + "WEIBULL.DIST", "ZTEST", 0 }; diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx index dc8c8b4..e8eefa3 100644 --- a/sc/source/core/inc/interpre.hxx +++ b/sc/source/core/inc/interpre.hxx @@ -725,6 +725,7 @@ double GetLogGamma(double x); double GetBeta(double fAlpha, double fBeta); double GetLogBeta(double fAlpha, double fBeta); double GetBinomDistPMF(double x, double n, double p); //probability mass function +double GetHypGeomDist( double x, double n, double M, double N ); void ScLogGamma(); void ScGamma(); void ScPhi(); @@ -745,6 +746,7 @@ void ScVariationen(); void ScVariationen2(); void ScB(); void ScHypGeomDist(); +void ScHypGeomDist_MS(); void ScLogNormDist(); void ScLogNormInv(); void ScTDist(); diff --git a/sc/source/core/tool/interpr3.cxx b/sc/source/core/tool/interpr3.cxx index 515530b..0cb0cc8 100644 --- a/sc/source/core/tool/interpr3.cxx +++ b/sc/source/core/tool/interpr3.cxx @@ -1738,12 +1738,6 @@ static void lcl_PutFactorialElements( ::std::vector< double >& cn, double fLower /** Calculates a value of the hypergeometric distribution. - The algorithm is designed to avoid unnecessary multiplications and division - by expanding all factorial elements (9 of them). It is done by excluding - those ranges that overlap in the numerator and the denominator. This allows - for a fast calculation for large values which would otherwise cause an overflow - in the intermediate values. - @author Kohei Yoshida <ko...@openoffice.org> @see #i47296# @@ -1751,8 +1745,6 @@ static void lcl_PutFactorialElements( ::std::vector< double >& cn, double fLower */ void ScInterpreter::ScHypGeomDist() { - const size_t nMaxArraySize = 500000; // arbitrary max array size - if ( !MustHaveParamCount( GetByte(), 4 ) ) return; @@ -1767,6 +1759,63 @@ void ScInterpreter::ScHypGeomDist() return; } + PushDouble( GetHypGeomDist( x, n, M, N ) ); +} + +/** Calculates a value of the hypergeometric distribution (Excel 2010 function). + + This function has an extra argument bCumulative as compared to ScHypGeomDist(), + which only calculates the non-cumulative distribution. + + @see fdo#71722 +*/ +void ScInterpreter::ScHypGeomDist_MS() +{ + if ( !MustHaveParamCount( GetByte(), 5 ) ) + return; + + bool bCumulative = GetBool(); + double N = ::rtl::math::approxFloor(GetDouble()); + double M = ::rtl::math::approxFloor(GetDouble()); + double n = ::rtl::math::approxFloor(GetDouble()); + double x = ::rtl::math::approxFloor(GetDouble()); + + if( (x < 0.0) || (n < x) || (M < x) || (N < n) || (N < M) || (x < n - N + M) ) + { + PushIllegalArgument(); + return; + } + + if ( bCumulative ) + { + double fVal = 0.0; + + for ( int i = 0; i <= x && !nGlobalError; i++ ) + fVal += GetHypGeomDist( i, n, M, N ); + + PushDouble( fVal ); + } + else + PushDouble( GetHypGeomDist( x, n, M, N ) ); +} + +/** Calculates a value of the hypergeometric distribution. + + The algorithm is designed to avoid unnecessary multiplications and division + by expanding all factorial elements (9 of them). It is done by excluding + those ranges that overlap in the numerator and the denominator. This allows + for a fast calculation for large values which would otherwise cause an overflow + in the intermediate values. + + @author Kohei Yoshida <ko...@openoffice.org> + + @see #i47296# + + */ +double ScInterpreter::GetHypGeomDist( double x, double n, double M, double N ) +{ + const size_t nMaxArraySize = 500000; // arbitrary max array size + typedef ::std::vector< double > HypContainer; HypContainer cnNumer, cnDenom; @@ -1775,7 +1824,7 @@ void ScInterpreter::ScHypGeomDist() if ( nEstContainerSize > nMaxSize ) { PushNoValue(); - return; + return 0; } cnNumer.reserve( nEstContainerSize + 10 ); cnDenom.reserve( nEstContainerSize + 10 ); @@ -1959,7 +2008,7 @@ void ScInterpreter::ScHypGeomDist() fFactor *= fEnum / fDenom; } - PushDouble(fFactor); + return fFactor; } void ScInterpreter::ScGammaDist() diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx index 38d73b0..d230ac8 100644 --- a/sc/source/core/tool/interpr4.cxx +++ b/sc/source/core/tool/interpr4.cxx @@ -4099,15 +4099,18 @@ StackVar ScInterpreter::Interpret() case ocMatRef : ScMatRef(); break; case ocB : ScB(); break; case ocNormDist : ScNormDist(); break; - case ocExpDist : ScExpDist(); break; + case ocExpDist : + case ocExpDist_MS : ScExpDist(); break; case ocBinomDist : case ocBinomDist_MS : ScBinomDist(); break; - case ocPoissonDist : ScPoissonDist(); break; + case ocPoissonDist : + case ocPoissonDist_MS : ScPoissonDist(); break; case ocKombin : ScKombin(); break; case ocKombin2 : ScKombin2(); break; case ocVariationen : ScVariationen(); break; case ocVariationen2 : ScVariationen2(); break; case ocHypGeomDist : ScHypGeomDist(); break; + case ocHypGeomDist_MS : ScHypGeomDist_MS(); break; case ocLogNormDist : ScLogNormDist(); break; case ocTDist : ScTDist(); break; case ocFDist : @@ -4127,7 +4130,8 @@ StackVar ScInterpreter::Interpret() case ocMedian : ScMedian(); break; case ocGeoMean : ScGeoMean(); break; case ocHarMean : ScHarMean(); break; - case ocWeibull : ScWeibull(); break; + case ocWeibull : + case ocWeibull_MS : ScWeibull(); break; case ocBinomInv : case ocKritBinom : ScCritBinom(); break; case ocNegBinomVert : ScNegBinomDist(); break; diff --git a/sc/source/filter/excel/xlformula.cxx b/sc/source/filter/excel/xlformula.cxx index b525d75..67d21ee 100644 --- a/sc/source/filter/excel/xlformula.cxx +++ b/sc/source/filter/excel/xlformula.cxx @@ -429,28 +429,32 @@ static const XclFunctionInfo saFuncTable_Oox[] = */ static const XclFunctionInfo saFuncTable_2010[] = { - EXC_FUNCENTRY_V_VA( ocCovarianceP, 2, 2, 0, "COVARIANCE.P" ), - EXC_FUNCENTRY_V_VA( ocCovarianceS, 2, 2, 0, "COVARIANCE.S" ), - EXC_FUNCENTRY_V_RX( ocStDevP_MS, 1, MX, 0, "STDEV.P" ), - EXC_FUNCENTRY_V_RX( ocStDevS, 1, MX, 0, "STDEV.S" ), - EXC_FUNCENTRY_V_RX( ocVarP_MS, 1, MX, 0, "VAR.P" ), - EXC_FUNCENTRY_V_RX( ocVarS, 1, MX, 0, "VAR.S" ), - EXC_FUNCENTRY_V_VR( ocBetaDist_MS, 4, 6, 0, "BETA.DIST" ), - EXC_FUNCENTRY_V_VR( ocBetaInv_MS, 3, 5, 0, "BETA.INV" ), - EXC_FUNCENTRY_V_VR( ocBinomDist_MS, 4, 4, 0, "BINOM.DIST" ), - EXC_FUNCENTRY_V_VR( ocBinomInv, 3, 3, 0, "BINOM.INV" ), - EXC_FUNCENTRY_V_VR( ocChiSqDist_MS, 3, 3, 0, "CHISQ.DIST" ), - EXC_FUNCENTRY_V_VR( ocChiSqInv_MS, 2, 2, 0, "CHISQ.INV" ), - EXC_FUNCENTRY_V_VR( ocChiDist_MS, 2, 2, 0, "CHISQ.DIST.RT" ), - EXC_FUNCENTRY_V_VR( ocChiInv_MS, 2, 2, 0, "CHISQ.INV.RT" ), - EXC_FUNCENTRY_V_VR( ocChiTest_MS, 2, 2, 0, "CHISQ.TEST" ), - EXC_FUNCENTRY_V_VR( ocConfidence_N, 3, 3, 0, "CONFIDENCE.NORM" ), - EXC_FUNCENTRY_V_VR( ocConfidence_T, 3, 3, 0, "CONFIDENCE.T" ), - EXC_FUNCENTRY_V_VR( ocFDist_LT, 4, 4, 0, "F.DIST" ), - EXC_FUNCENTRY_V_VR( ocFDist_RT, 3, 3, 0, "F.DIST.RT" ), - EXC_FUNCENTRY_V_VR( ocFInv_LT, 3, 3, 0, "F.INV" ), - EXC_FUNCENTRY_V_VR( ocFInv_RT, 3, 3, 0, "F.INV.RT" ), - EXC_FUNCENTRY_V_VR( ocFTest_MS, 2, 2, 0, "F.TEST" ) + EXC_FUNCENTRY_V_VA( ocCovarianceP, 2, 2, 0, "COVARIANCE.P" ), + EXC_FUNCENTRY_V_VA( ocCovarianceS, 2, 2, 0, "COVARIANCE.S" ), + EXC_FUNCENTRY_V_RX( ocStDevP_MS, 1, MX, 0, "STDEV.P" ), + EXC_FUNCENTRY_V_RX( ocStDevS, 1, MX, 0, "STDEV.S" ), + EXC_FUNCENTRY_V_RX( ocVarP_MS, 1, MX, 0, "VAR.P" ), + EXC_FUNCENTRY_V_RX( ocVarS, 1, MX, 0, "VAR.S" ), + EXC_FUNCENTRY_V_VR( ocBetaDist_MS, 4, 6, 0, "BETA.DIST" ), + EXC_FUNCENTRY_V_VR( ocBetaInv_MS, 3, 5, 0, "BETA.INV" ), + EXC_FUNCENTRY_V_VR( ocBinomDist_MS, 4, 4, 0, "BINOM.DIST" ), + EXC_FUNCENTRY_V_VR( ocBinomInv, 3, 3, 0, "BINOM.INV" ), + EXC_FUNCENTRY_V_VR( ocChiSqDist_MS, 3, 3, 0, "CHISQ.DIST" ), + EXC_FUNCENTRY_V_VR( ocChiSqInv_MS, 2, 2, 0, "CHISQ.INV" ), + EXC_FUNCENTRY_V_VR( ocChiDist_MS, 2, 2, 0, "CHISQ.DIST.RT" ), + EXC_FUNCENTRY_V_VR( ocChiInv_MS, 2, 2, 0, "CHISQ.INV.RT" ), + EXC_FUNCENTRY_V_VR( ocChiTest_MS, 2, 2, 0, "CHISQ.TEST" ), + EXC_FUNCENTRY_V_VR( ocConfidence_N, 3, 3, 0, "CONFIDENCE.NORM" ), + EXC_FUNCENTRY_V_VR( ocConfidence_T, 3, 3, 0, "CONFIDENCE.T" ), + EXC_FUNCENTRY_V_VR( ocFDist_LT, 4, 4, 0, "F.DIST" ), + EXC_FUNCENTRY_V_VR( ocFDist_RT, 3, 3, 0, "F.DIST.RT" ), + EXC_FUNCENTRY_V_VR( ocFInv_LT, 3, 3, 0, "F.INV" ), + EXC_FUNCENTRY_V_VR( ocFInv_RT, 3, 3, 0, "F.INV.RT" ), + EXC_FUNCENTRY_V_VR( ocFTest_MS, 2, 2, 0, "F.TEST" ), + EXC_FUNCENTRY_V_VR( ocExpDist_MS, 3, 3, 0, "EXPON.DIST" ), + EXC_FUNCENTRY_V_VR( ocHypGeomDist_MS, 5, 5, 0, "HYPGEOM.DIST" ), + EXC_FUNCENTRY_V_VR( ocPoissonDist_MS, 3, 3, 0, "POISSON.DIST" ), + EXC_FUNCENTRY_V_VR( ocWeibull_MS, 4, 4, 0, "WEIBULL.DIST" ) }; /** Functions new in Excel 2013. diff --git a/sc/source/filter/oox/formulabase.cxx b/sc/source/filter/oox/formulabase.cxx index b2376f4..ef8c926 100644 --- a/sc/source/filter/oox/formulabase.cxx +++ b/sc/source/filter/oox/formulabase.cxx @@ -768,7 +768,11 @@ static const FunctionData saFuncTable2010[] = { "COM.MICROSOFT.F.DIST.RT", "F.DIST.RT", NOID, NOID, 3, 3, V, { VR }, FUNCFLAG_MACROCALL_NEW }, { "COM.MICROSOFT.F.INV", "F.INV", NOID, NOID, 3, 3, V, { VR }, FUNCFLAG_MACROCALL_NEW }, { "COM.MICROSOFT.F.INV.RT", "F.INV.RT", NOID, NOID, 3, 3, V, { VR }, FUNCFLAG_MACROCALL_NEW }, - { "COM.MICROSOFT.F.TEST", "F.TEST", NOID, NOID, 2, 2, V, { VA }, FUNCFLAG_MACROCALL_NEW } + { "COM.MICROSOFT.F.TEST", "F.TEST", NOID, NOID, 2, 2, V, { VA }, FUNCFLAG_MACROCALL_NEW }, + { "COM.MICROSOFT.EXPON.DIST", "EXPON.DIST", NOID, NOID, 3, 3, V, { VR }, FUNCFLAG_MACROCALL_NEW }, + { "COM.MICROSOFT.HYPGEOM.DIST", "HYPGEOM.DIST", NOID, NOID, 5, 5, V, { VR }, FUNCFLAG_MACROCALL_NEW }, + { "COM.MICROSOFT.POISSON.DIST", "POISSON.DIST", NOID, NOID, 3, 3, V, { VR }, FUNCFLAG_MACROCALL_NEW }, + { "COM.MICROSOFT.WEIBULL.DIST", "WEIBULL.DIST", NOID, NOID, 4, 4, V, { VR }, FUNCFLAG_MACROCALL_NEW } }; /** Functions new in Excel 2013. diff --git a/sc/source/ui/src/scfuncs.src b/sc/source/ui/src/scfuncs.src index 36dee21..ba670a4 100644 --- a/sc/source/ui/src/scfuncs.src +++ b/sc/source/ui/src/scfuncs.src @@ -6295,6 +6295,46 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS2 Text [ en-US ] = "0 or FALSE calculates the probability density function. Any other value or TRUE or omitted calculates the cumulative distribution function." ; }; }; + // -=*# Resource for function POISSON.DIST #*=- + Resource SC_OPCODE_POISSON_DIST_MS + { + String 1 // Description + { + Text [ en-US ] = "Returns the Poisson distribution." ; + }; + ExtraData = + { + 0; + ID_FUNCTION_GRP_STATISTIC; + U2S( HID_FUNC_POISSON_DIST_MS ); + 3; 0; 0; 1; + 0; + }; + String 2 // Name of Parameter 1 + { + Text [ en-US ] = "Number" ; + }; + String 3 // Description of Parameter 1 + { + Text [ en-US ] = "The value for which the Poisson distribution is to be calculated." ; + }; + String 4 // Name of Parameter 2 + { + Text [ en-US ] = "mean" ; + }; + String 5 // Description of Parameter 2 + { + Text [ en-US ] = "Mean. The mean value of the Poisson distribution." ; + }; + String 6 // Name of Parameter 3 + { + Text [ en-US ] = "Cumulative" ; + }; + String 7 // Description of Parameter 3 + { + Text [ en-US ] = "0 or FALSE calculates the probability density function. Any other value or TRUE or omitted calculates the cumulative distribution function." ; + }; + }; // -=*# Resource for function NORMVERT #*=- Resource SC_OPCODE_NORM_DIST { @@ -6559,6 +6599,46 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS2 Text [ en-US ] = "Cumulated. C=0 calculates the density function, C=1 the distribution." ; }; }; + // -=*# Resource for function EXPON.DIST #*=- + Resource SC_OPCODE_EXP_DIST_MS + { + String 1 // Description + { + Text [ en-US ] = "Values of the exponential distribution." ; + }; + ExtraData = + { + 0; + ID_FUNCTION_GRP_STATISTIC; + U2S( HID_FUNC_EXP_DIST_MS ); + 3; 0; 0; 0; + 0; + }; + String 2 // Name of Parameter 1 + { + Text [ en-US ] = "Number" ; + }; + String 3 // Description of Parameter 1 + { + Text [ en-US ] = "The value to which the exponential distribution is to be calculated." ; + }; + String 4 // Name of Parameter 2 + { + Text [ en-US ] = "lambda" ; + }; + String 5 // Description of Parameter 2 + { + Text [ en-US ] = "The parameters of the exponential distribution." ; + }; + String 6 // Name of Parameter 3 + { + Text [ en-US ] = "C" ; + }; + String 7 // Description of Parameter 3 + { + Text [ en-US ] = "Cumulated. C=0 calculates the density function, C=1 the distribution." ; + }; + }; // -=*# Resource for function GAMMAVERT #*=- Resource SC_OPCODE_GAMMA_DIST { @@ -6985,6 +7065,54 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS2 Text [ en-US ] = "Cumulated. C=0 calculates the density function, C=1 the distribution." ; }; }; + // -=*# Resource for function WEIBULL.DIST #*=- + Resource SC_OPCODE_WEIBULL_MS + { + String 1 // Description + { + Text [ en-US ] = "Returns the values of the Weibull distribution." ; + }; + ExtraData = + { + 0; + ID_FUNCTION_GRP_STATISTIC; + U2S( HID_FUNC_WEIBULL_DIST_MS ); + 4; 0; 0; 0; 0; + 0; + }; + String 2 // Name of Parameter 1 + { + Text [ en-US ] = "Number" ; + }; + String 3 // Description of Parameter 1 + { + Text [ en-US ] = "The value for which the Weibull distribution is to be calculated." ; + }; + String 4 // Name of Parameter 2 + { + Text [ en-US ] = "Alpha" ; + }; + String 5 // Description of Parameter 2 + { + Text [ en-US ] = "The Alpha parameter of the Weibull distribution." ; + }; + String 6 // Name of Parameter 3 + { + Text [ en-US ] = "beta" ; + }; + String 7 // Description of Parameter 3 + { + Text [ en-US ] = "The Beta parameter of the Weibull distribution." ; + }; + String 8 // Name of Parameter 4 + { + Text [ en-US ] = "C" ; + }; + String 9 // Description of Parameter 4 + { + Text [ en-US ] = "Cumulated. C=0 calculates the density function, C=1 the distribution." ; + }; + }; // -=*# Resource for function HYPGEOMVERT #*=- Resource SC_OPCODE_HYP_GEOM_DIST { @@ -7033,6 +7161,62 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS2 Text [ en-US ] = "The population size." ; }; }; + // -=*# Resource for function HYPGEOM.DIST #*=- + Resource SC_OPCODE_HYP_GEOM_DIST_MS + { + String 1 // Description + { + Text [ en-US ] = "Values of the hypergeometric distribution." ; + }; + ExtraData = + { + 0; + ID_FUNCTION_GRP_STATISTIC; + U2S( HID_FUNC_HYP_GEOM_DIST_MS ); + 5; 0; 0; 0; 0; + 0; + }; + String 2 // Name of Parameter 1 + { + Text [ en-US ] = "X" ; + }; + String 3 // Description of Parameter 1 + { + Text [ en-US ] = "The number of successes in the sample." ; + }; + String 4 // Name of Parameter 2 + { + Text [ en-US ] = "n_sample" ; + }; + String 5 // Description of Parameter 2 + { + Text [ en-US ] = "The size of the sample." ; + }; + String 6 // Name of Parameter 3 + { + Text [ en-US ] = "successes" ; + }; + String 7 // Description of Parameter 3 + { + Text [ en-US ] = "The number of successes in the population." ; + }; + String 8 // Name of Parameter 4 + { + Text [ en-US ] = "n_population" ; + }; + String 9 // Description of Parameter 4 + { + Text [ en-US ] = "The population size." ; + }; + String 10 // Name of Parameter 5 + { + Text [ en-US ] = "C" ; + }; + String 11 // Description of Parameter 5 + { + Text [ en-US ] = "Cumulated. TRUE calculates the probabilty mass function, FALSE the cumulative distribution function." ; + }; + }; // -=*# Resource for function TVERT #*=- Resource SC_OPCODE_T_DIST { commit 73ee1d61ddbda7271623f5dccd0c647d614d8d1e Author: Winfried Donkers <winfrieddonk...@libreoffice.org> Date: Thu Nov 21 13:31:46 2013 +0100 fdo#71350 fix incorrect calculation of Excel function CONFIDENCE.T Change-Id: I94202bebcc7deded51636f4bf7f203254a31931f Reviewed-on: https://gerrit.libreoffice.org/6751 Reviewed-by: Eike Rathke <er...@redhat.com> Tested-by: Eike Rathke <er...@redhat.com> (cherry picked from commit d8a023d41ec85538bc0103c063ee722e1de67c2f) diff --git a/sc/source/core/tool/interpr3.cxx b/sc/source/core/tool/interpr3.cxx index 2f534f6..515530b 100644 --- a/sc/source/core/tool/interpr3.cxx +++ b/sc/source/core/tool/interpr3.cxx @@ -2309,7 +2309,7 @@ void ScInterpreter::ScConfidenceT() if (sigma <= 0.0 || alpha <= 0.0 || alpha >= 1.0 || n < 1.0) PushIllegalArgument(); else - PushDouble( sigma * GetTInv( 1 - alpha / 2, n - 1 ) / sqrt( n ) ); + PushDouble( sigma * GetTInv( alpha, n - 1 ) / sqrt( n ) ); } } commit d9e148c6bfbf4f29b477a5df381193c4f5a3ef36 Author: Eike Rathke <er...@redhat.com> Date: Thu Nov 21 16:05:37 2013 +0100 removed declared but undefined LanguageTagImpl::convertFromRtlLocale() Change-Id: I928fb77181991948216bb18cdfcea0816218a2b9 (cherry picked from commit 5d34cd53e4cb63364cc3a369f7f97fa25d9741cf) diff --git a/i18nlangtag/source/languagetag/languagetag.cxx b/i18nlangtag/source/languagetag/languagetag.cxx index 3a15ecc..68ee64c 100644 --- a/i18nlangtag/source/languagetag/languagetag.cxx +++ b/i18nlangtag/source/languagetag/languagetag.cxx @@ -301,8 +301,6 @@ private: void convertLangToLocale(); void convertLangToBcp47(); - void convertFromRtlLocale(); - /** @return whether BCP 47 language tag string was changed. */ bool canonicalize(); commit fb0a970e82d5cee736ee1f50d186c648e1890116 Author: Eike Rathke <er...@redhat.com> Date: Thu Nov 21 15:57:53 2013 +0100 handleVendorVariant() strip in case some was injected Change-Id: I73c42a99671524e9fb186257a9bc943d514958c2 (cherry picked from commit 017a2a368cee1f6f5e7c6e18e65cbbc1a54efe47) diff --git a/i18nlangtag/source/languagetag/languagetag.cxx b/i18nlangtag/source/languagetag/languagetag.cxx index 60e8c12..3a15ecc 100644 --- a/i18nlangtag/source/languagetag/languagetag.cxx +++ b/i18nlangtag/source/languagetag/languagetag.cxx @@ -230,6 +230,17 @@ void LiblantagDataRef::setupDataPath() } +/* TODO: we could transform known vendor and browser-specific variants to known + * BCP 47 if available. For now just remove them to not confuse any later + * treatments that check for empty variants. This vendor stuff was never + * supported anyway. */ +static void handleVendorVariant( com::sun::star::lang::Locale & rLocale ) +{ + if (!rLocale.Variant.isEmpty() && rLocale.Language != I18NLANGTAG_QLT) + rLocale.Variant = OUString(); +} + + class LanguageTagImpl { public: @@ -483,6 +494,7 @@ LanguageTag::LanguageTag( const com::sun::star::lang::Locale & rLocale ) mbInitializedLangID( false), mbIsFallback( false) { + handleVendorVariant( maLocale); } @@ -1025,6 +1037,7 @@ LanguageTag & LanguageTag::reset( const com::sun::star::lang::Locale & rLocale ) maLocale = rLocale; mbSystemLocale = rLocale.Language.isEmpty(); mbInitializedLocale = !mbSystemLocale; + handleVendorVariant( maLocale); return *this; } commit 7257023e6e831f2ad5d4b56a73c84652b2c6cd9c Author: Eike Rathke <er...@redhat.com> Date: Thu Nov 21 14:14:43 2013 +0100 documented BCP 47 semantics Change-Id: Ia2fad8e79833a66bb3e95047fc5885880d6da17c (cherry picked from commit e3f30efe9f466e776e19210c0e1bccea97e6be49) diff --git a/udkapi/com/sun/star/lang/Locale.idl b/udkapi/com/sun/star/lang/Locale.idl index 224806c..c1a4c5d 100644 --- a/udkapi/com/sun/star/lang/Locale.idl +++ b/udkapi/com/sun/star/lang/Locale.idl @@ -51,27 +51,34 @@ module com { module sun { module star { module lang { */ published struct Locale { - /** specifies an <strong>ISO Language Code</strong>. + /** specifies an <strong>ISO 639 Language Code</strong>. - <p>These codes are the lower-case two-letter codes as defined by - ISO-639. You can find a full list of these codes at a number of + <p>These codes are preferably the lower-case two-letter codes as + defined by ISO 639-1, or three-letter codes as defined by ISO + 639-3. You can find a full list of these codes at a number of sites, such as: <br/> - <a href="http://www.chemie.fu-berlin.de/diverse/doc/ISO_639.html"> - <code>http://www.chemie.fu-berlin.de/diverse/doc/ISO_639.html</code></a>. + <a href="http://sil.org/iso639-3/codes.asp"> + <code>http://sil.org/iso639-3/codes.asp</code></a>. </p> <p>If this field contains an empty string, the meaning depends on the context.</p> + + <p>Since LibreOffice 4.2, if the locale can not be represented + using only ISO 639 and ISO 3166 codes this field contains the + ISO 639-3 reserved for local use code "<strong>qlt</strong>" and + a <strong>BCP 47</strong> language tag is present in the Variant + field. </p> */ string Language; - /** specifies an <strong>ISO Country Code</strong>. + /** specifies an <strong>ISO 3166 Country Code</strong>. <p>These codes are the upper-case two-letter codes as - defined by ISO-3166. You can find a full list of these codes at a - number of sites, such as: <br/> - <a href="http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html"> - <code>http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html</code></a>. + defined by ISO 3166-1. You can find a full list of these codes + at a number of sites, such as: <br/> + <a href="http://www.iso.org/iso/country_codes/iso_3166_code_lists/country_names_and_code_elements.htm"> + <code>http://www.iso.org/iso/country_codes/iso_3166_code_lists/country_names_and_code_elements.htm</code></a>. </p> <p>If this field contains an empty string, the meaning depends on the @@ -79,14 +86,22 @@ published struct Locale */ string Country; - /** contains a variant of the locale; codes are vendor and - browser-specific. + /** specifies a <strong>BCP 47</strong> Language Tag. + + <p>Since LibreOffice 4.2, <strong>if</strong> the Language field + is the code "<strong>qlt</strong>" this field contains the full + BCP 47 language tag. If the Language field is not "qlt" this + field is empty. </p> - <p>For example, use WIN for Windows, MAC for Macintosh, and POSIX - for POSIX. Wherever there are two variants, separate them with an - underscore, and put the most important one first. For example, a - traditional Spanish collation might construct a locale with parameters - for language, country and variant as: "es", "ES", "Traditional_WIN".</p> + <p>You can find BCP 47 language tag resources at <br/> + <a href="http://www.langtag.net/"> + <code>http://www.langtag.net/</code></a>. </p> + + <p>Earlier versions of the documentation mentioned "vendor and + browser-specific" codes but that was never supported. Use of any + arbitrary strings in the Variant field that do not form a valid + BCP 47 language tag is <strong>strongly deprecated</strong>. + </p> */ string Variant; _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits