[Libreoffice-commits] core.git: formula/source include/formula sc/inc sc/qa sc/source

Winfried Donkers winfrieddonkers at libreoffice.org
Tue Oct 6 14:21:43 PDT 2015


 formula/source/core/api/FormulaCompiler.cxx        |   71 ++++++++++++++++-----
 formula/source/core/resource/core_resource.src     |    9 ++
 include/formula/compiler.hrc                       |    3 
 include/formula/opcode.hxx                         |    1 
 sc/inc/helpids.h                                   |    1 
 sc/qa/unit/data/contentCSV/date-time-functions.csv |    4 -
 sc/qa/unit/data/ods/date-time-functions.ods        |binary
 sc/qa/unit/ucalc.cxx                               |    1 
 sc/source/core/inc/interpre.hxx                    |    1 
 sc/source/core/tool/interpr2.cxx                   |   39 +++++++++++
 sc/source/core/tool/interpr4.cxx                   |    1 
 sc/source/filter/excel/xlformula.cxx               |    3 
 sc/source/filter/oox/formulabase.cxx               |    4 -
 sc/source/ui/src/scfuncs.src                       |   26 +++++++
 14 files changed, 141 insertions(+), 23 deletions(-)

New commits:
commit f830600ece806ec365a4839e79afabe183c5e36d
Author: Winfried Donkers <winfrieddonkers at libreoffice.org>
Date:   Tue Sep 22 10:40:25 2015 +0200

    tdf#50950 Add ODFF1.2 Calc function ISOWEEKNUM,
    
    make Calc function WEEKNUM compliant with ODFF1.2,
    provide backward compatibility for Calc function WEEKNUM,
    add unit tests for ISOWEEKNUM, WEEKNUM and backward compatibility.
    
    Change-Id: I63af5543cea2f470d710462e55404ac754022c89
    Reviewed-on: https://gerrit.libreoffice.org/18760
    Reviewed-by: Eike Rathke <erack at redhat.com>
    Tested-by: Eike Rathke <erack at redhat.com>

diff --git a/formula/source/core/api/FormulaCompiler.cxx b/formula/source/core/api/FormulaCompiler.cxx
index 4ee0f72..9d613e9 100644
--- a/formula/source/core/api/FormulaCompiler.cxx
+++ b/formula/source/core/api/FormulaCompiler.cxx
@@ -1247,23 +1247,66 @@ void FormulaCompiler::Factor()
         else if( eOp == ocNot || eOp == ocNeg
               || (SC_OPCODE_START_1_PAR <= eOp && eOp < SC_OPCODE_STOP_1_PAR) )
         {
-            pFacToken = mpToken;
-            eOp = NextToken();
-            if( nNumFmt == css::util::NumberFormat::UNDEFINED && eOp == ocNot )
-                nNumFmt = css::util::NumberFormat::LOGICAL;
-            if (eOp == ocOpen)
+            if (eOp == ocIsoWeeknum && FormulaGrammar::isODFF( meGrammar ))
             {
-                NextToken();
-                eOp = Expression();
+                // tdf#50950 ocIsoWeeknum can have 2 arguments when saved by older versions of Calc;
+                // the opcode then has to be changed to ocWeek for backward compatibilty
+                pFacToken = mpToken;
+                eOp = NextToken();
+                bool bNoParam = false;
+                if (eOp == ocOpen)
+                {
+                    eOp = NextToken();
+                    if (eOp == ocClose)
+                        bNoParam = true;
+                    else
+                        eOp = Expression();
+                }
+                else
+                    SetError( errPairExpected);
+                sal_uInt8 nSepCount = 0;
+                if( !bNoParam )
+                {
+                    nSepCount++;
+                    while ((eOp == ocSep) && (!pArr->GetCodeError() || !mbStopOnError))
+                    {
+                        nSepCount++;
+                        NextToken();
+                        eOp = Expression();
+                    }
+                }
+                if (eOp != ocClose)
+                    SetError( errPairExpected);
+                else
+                    eOp = NextToken();
+                pFacToken->SetByte( nSepCount );
+                if (nSepCount == 2)
+                {
+                    pFacToken->NewOpCode( ocWeek, FormulaToken::PrivateAccess());
+                }
+                PutCode( pFacToken );
             }
             else
-                SetError( errPairExpected);
-            if (eOp != ocClose)
-                SetError( errPairExpected);
-            else if ( !pArr->GetCodeError() )
-                pFacToken->SetByte( 1 );
-            PutCode( pFacToken );
-            eOp = NextToken();
+            {
+                // standard handling of ocNot, ocNeg and 1-parameter opcodes
+                pFacToken = mpToken;
+                eOp = NextToken();
+                if( nNumFmt == css::util::NumberFormat::UNDEFINED && eOp == ocNot )
+                    nNumFmt = css::util::NumberFormat::LOGICAL;
+                if (eOp == ocOpen)
+                {
+                    NextToken();
+                    eOp = Expression();
+                }
+                else
+                    SetError( errPairExpected);
+                if (eOp != ocClose)
+                    SetError( errPairExpected);
+                else if ( !pArr->GetCodeError() )
+                    pFacToken->SetByte( 1 );
+                PutCode( pFacToken );
+                eOp = NextToken();
+            }
         }
         else if ((SC_OPCODE_START_2_PAR <= eOp && eOp < SC_OPCODE_STOP_2_PAR)
                 || eOp == ocExternal
diff --git a/formula/source/core/resource/core_resource.src b/formula/source/core/resource/core_resource.src
index ed0aeca..90cd6e5 100644
--- a/formula/source/core/resource/core_resource.src
+++ b/formula/source/core/resource/core_resource.src
@@ -389,7 +389,8 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH_ODFF
     String SC_OPCODE_BETA_INV { Text = "BETAINV" ; };
     String SC_OPCODE_BETA_DIST_MS { Text = "COM.MICROSOFT.BETA.DIST" ; };
     String SC_OPCODE_BETA_INV_MS { Text = "COM.MICROSOFT.BETA.INV" ; };
-    String SC_OPCODE_WEEK { Text = "ISOWEEKNUM" ; };
+    String SC_OPCODE_WEEK { Text = "WEEKNUM" ; };
+    String SC_OPCODE_ISOWEEKNUM { Text = "ISOWEEKNUM" ; };
     String SC_OPCODE_EASTERSUNDAY { Text = "ORG.OPENOFFICE.EASTERSUNDAY" ; };
     String SC_OPCODE_GET_DAY_OF_WEEK { Text = "WEEKDAY" ; };
     String SC_OPCODE_NETWORKDAYS { Text = "NETWORKDAYS" ; };
@@ -811,6 +812,7 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH_OOXML
     String SC_OPCODE_BETA_DIST_MS { Text = "_xlfn.BETA.DIST" ; };
     String SC_OPCODE_BETA_INV_MS { Text = "_xlfn.BETA.INV" ; };
     String SC_OPCODE_WEEK { Text = "WEEKNUM" ; };
+    String SC_OPCODE_ISOWEEKNUM { Text = "_xlfn.ISOWEEKNUM" ; };
     String SC_OPCODE_EASTERSUNDAY { Text = "EASTERSUNDAY" ; };
     String SC_OPCODE_GET_DAY_OF_WEEK { Text = "WEEKDAY" ; };
     String SC_OPCODE_NETWORKDAYS { Text = "NETWORKDAYS" ; };
@@ -1234,6 +1236,7 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH
     String SC_OPCODE_BETA_DIST_MS { Text = "BETA.DIST" ; };
     String SC_OPCODE_BETA_INV_MS { Text = "BETA.INV" ; };
     String SC_OPCODE_WEEK { Text = "WEEKNUM" ; };
+    String SC_OPCODE_ISOWEEKNUM { Text = "ISOWEEKNUM" ; };
     String SC_OPCODE_EASTERSUNDAY { Text = "EASTERSUNDAY" ; };
     String SC_OPCODE_GET_DAY_OF_WEEK { Text = "WEEKDAY" ; };
     String SC_OPCODE_NETWORKDAYS { Text = "NETWORKDAYS" ; };
@@ -2698,6 +2701,10 @@ Resource RID_STRLIST_FUNCTION_NAMES
     {
         Text [ en-US ] = "WEEKNUM" ;
     };
+    String SC_OPCODE_ISOWEEKNUM
+    {
+        Text [ en-US ] = "ISOWEEKNUM" ;
+    };
     String SC_OPCODE_EASTERSUNDAY
     {
         Text [ en-US ] = "EASTERSUNDAY" ;
diff --git a/include/formula/compiler.hrc b/include/formula/compiler.hrc
index 9d45b9a..984ec02 100644
--- a/include/formula/compiler.hrc
+++ b/include/formula/compiler.hrc
@@ -204,7 +204,8 @@
 #define SC_OPCODE_ERFC_MS           174
 #define SC_OPCODE_ERROR_TYPE_ODF    175
 #define SC_OPCODE_ENCODEURL         176
-#define SC_OPCODE_STOP_1_PAR        177
+#define SC_OPCODE_ISOWEEKNUM        177
+#define SC_OPCODE_STOP_1_PAR        178
 
 /*** Functions with more than one parameters ***/
 #define SC_OPCODE_START_2_PAR       201
diff --git a/include/formula/opcode.hxx b/include/formula/opcode.hxx
index 806147c..0c4c8e8 100644
--- a/include/formula/opcode.hxx
+++ b/include/formula/opcode.hxx
@@ -449,6 +449,7 @@ enum OpCode : sal_uInt16
         ocBitLshift         = SC_OPCODE_BITLSHIFT,
     // miscellaneous
         ocWeek              = SC_OPCODE_WEEK,
+        ocIsoWeeknum        = SC_OPCODE_ISOWEEKNUM,
         ocGetDayOfWeek      = SC_OPCODE_GET_DAY_OF_WEEK,
         ocNetWorkdays       = SC_OPCODE_NETWORKDAYS,
         ocNetWorkdays_MS    = SC_OPCODE_NETWORKDAYS_MS,
diff --git a/sc/inc/helpids.h b/sc/inc/helpids.h
index 1c45bbe..3b41eb8 100644
--- a/sc/inc/helpids.h
+++ b/sc/inc/helpids.h
@@ -284,6 +284,7 @@
 #define HID_FUNC_DATEDIF                                        "SC_HID_FUNC_DATEDIF"
 #define HID_FUNC_KALENDERWOCHE                                  "SC_HID_FUNC_KALENDERWOCHE"
 #define HID_FUNC_OSTERSONNTAG                                   "SC_HID_FUNC_OSTERSONNTAG"
+#define HID_FUNC_ISOWEEKNUM                                     "SC_HID_FUNC_ISOWEEKNUM"
 
 #define HID_FUNC_BW                                             "SC_HID_FUNC_BW"
 #define HID_FUNC_ZW                                             "SC_HID_FUNC_ZW"
diff --git a/sc/qa/unit/data/contentCSV/date-time-functions.csv b/sc/qa/unit/data/contentCSV/date-time-functions.csv
index a43bdc3..33aa540 100644
--- a/sc/qa/unit/data/contentCSV/date-time-functions.csv
+++ b/sc/qa/unit/data/contentCSV/date-time-functions.csv
@@ -19,7 +19,9 @@
 .18
 0,0.6666666667,0.5
 4,3,4
-1,52
+52
+1,1,52
+1,1
 52
 10,11
 52,52
diff --git a/sc/qa/unit/data/ods/date-time-functions.ods b/sc/qa/unit/data/ods/date-time-functions.ods
index 9f6e044..19244b6 100644
Binary files a/sc/qa/unit/data/ods/date-time-functions.ods and b/sc/qa/unit/data/ods/date-time-functions.ods differ
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index e6d9081..0dda665 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -2366,6 +2366,7 @@ void Test::testFunctionLists()
         "EASTERSUNDAY",
         "HOUR",
         "ISLEAPYEAR",
+        "ISOWEEKNUM",
         "MINUTE",
         "MONTH",
         "MONTHS",
diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx
index 85ede44..280d9d1 100644
--- a/sc/source/core/inc/interpre.hxx
+++ b/sc/source/core/inc/interpre.hxx
@@ -616,6 +616,7 @@ void ScGetMonth();
 void ScGetDay();
 void ScGetDayOfWeek();
 void ScGetWeekOfYear();
+void ScGetIsoWeekOfYear();
 void ScEasterSunday();
 sal_uInt16 GetWeekendAndHolidayMasks( const sal_uInt8 nParamCount, const sal_uInt32 nNullDate,
         ::std::vector<double>& rSortArray, bool bWeekendMask[ 7 ] );
diff --git a/sc/source/core/tool/interpr2.cxx b/sc/source/core/tool/interpr2.cxx
index 5699816..95fd1aa 100644
--- a/sc/source/core/tool/interpr2.cxx
+++ b/sc/source/core/tool/interpr2.cxx
@@ -213,7 +213,44 @@ void ScInterpreter::ScGetWeekOfYear()
 
         Date aDate = *(pFormatter->GetNullDate());
         aDate += (long)::rtl::math::approxFloor(GetDouble());
-        PushInt( (int) aDate.GetWeekOfYear( nFlag == 1 ? SUNDAY : MONDAY ));
+
+        sal_Int32 nMinimumNumberOfDaysInWeek;
+        DayOfWeek eFirstDayOfWeek;
+        switch ( nFlag )
+        {
+            case   1 :
+            case  11 :
+            case   2 :
+            case  12 :
+            case  13 :
+            case  14 :
+            case  15 :
+            case  16 :
+            case  17 :
+                eFirstDayOfWeek = (DayOfWeek) ( ( nFlag - 1 )  % 10 );
+                nMinimumNumberOfDaysInWeek = 1; //the week containing January 1 is week 1
+                break;
+            case  21 :
+            case 150 :
+                // ISO 8601
+                eFirstDayOfWeek = MONDAY;
+                nMinimumNumberOfDaysInWeek = 4;
+                break;
+            default :
+                PushIllegalArgument();
+                return;
+        }
+        PushInt( (int) aDate.GetWeekOfYear( eFirstDayOfWeek, nMinimumNumberOfDaysInWeek ) );
+    }
+}
+
+void ScInterpreter::ScGetIsoWeekOfYear()
+{
+    if ( MustHaveParamCount( GetByte(), 1 ) )
+    {
+        Date aDate = *(pFormatter->GetNullDate());
+        aDate += (long)::rtl::math::approxFloor(GetDouble());
+        PushInt( (int) aDate.GetWeekOfYear( MONDAY, 4 ) );
     }
 }
 
diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
index 211ac7c..e8a3b1d 100644
--- a/sc/source/core/tool/interpr4.cxx
+++ b/sc/source/core/tool/interpr4.cxx
@@ -3697,6 +3697,7 @@ StackVar ScInterpreter::Interpret()
                 case ocGetDay           : ScGetDay();                   break;
                 case ocGetDayOfWeek     : ScGetDayOfWeek();             break;
                 case ocWeek             : ScGetWeekOfYear();            break;
+                case ocIsoWeeknum       : ScGetIsoWeekOfYear();         break;
                 case ocEasterSunday     : ScEasterSunday();             break;
                 case ocNetWorkdays      : ScNetWorkdays( false);        break;
                 case ocNetWorkdays_MS   : ScNetWorkdays( true );        break;
diff --git a/sc/source/filter/excel/xlformula.cxx b/sc/source/filter/excel/xlformula.cxx
index 157d11b..9042933 100644
--- a/sc/source/filter/excel/xlformula.cxx
+++ b/sc/source/filter/excel/xlformula.cxx
@@ -545,7 +545,8 @@ static const XclFunctionInfo saFuncTable_2013[] =
     // IMCOSH, IMCOT, IMCSC, IMCSCH, IMSEC, IMSECH, IMSINH and IMTAN are
     // implemented in the Analysis Add-In.
     EXC_FUNCENTRY_V_RO(         ocIsFormula,     1,  1,  0,  "ISFORMULA" ),
-    EXC_FUNCENTRY_V_VR(         ocWeek,          1,  2,  0,  "ISOWEEKNUM" ),
+    EXC_FUNCENTRY_V_VR(         ocWeek,          1,  2,  0,  "WEEKNUM" ),
+    EXC_FUNCENTRY_V_VR(         ocIsoWeeknum,    1,  1,  0,  "ISOWEEKNUM" ),
     EXC_FUNCENTRY_A_VR(         ocMatrixUnit,    1,  1,  0,  "MUNIT" ),
     EXC_FUNCENTRY_V_VR(         ocNumberValue,   1,  3,  0,  "NUMBERVALUE" ),
     EXC_FUNCENTRY_V_VR(         ocDuration,      3,  3,  0,  "PDURATION" ),
diff --git a/sc/source/filter/oox/formulabase.cxx b/sc/source/filter/oox/formulabase.cxx
index b4bcb25..cdfc922 100644
--- a/sc/source/filter/oox/formulabase.cxx
+++ b/sc/source/filter/oox/formulabase.cxx
@@ -876,9 +876,7 @@ static const FunctionData saFuncTable2013[] =
     { "IMSINH",                 "IMSINH",               NOID,   NOID,   1,  1,  V, { VR }, FUNCFLAG_MACROCALL_NEW | FUNCFLAG_EXTERNAL },
     { "IMTAN",                  "IMTAN",                NOID,   NOID,   1,  1,  V, { VR }, FUNCFLAG_MACROCALL_NEW | FUNCFLAG_EXTERNAL },
     { "ISFORMULA",              "ISFORMULA",            NOID,   NOID,   1,  1,  V, { RO }, FUNCFLAG_MACROCALL_NEW },
-    /* FIXME: ISOWEEKNUM vs. WEEKNUM mess needs to be sorted out before we can
-     * import. */
-    { 0/*"ISOWEEKNUM"*/,        "ISOWEEKNUM",           NOID,   NOID,   1,  2,  V, { VR }, FUNCFLAG_MACROCALL_NEW },
+    { "ISOWEEKNUM",             "ISOWEEKNUM",           NOID,   NOID,   1,  1,  V, { VR }, FUNCFLAG_MACROCALL_NEW },
     { "MUNIT",                  "MUNIT",                NOID,   NOID,   1,  1,  A, { VR }, FUNCFLAG_MACROCALL_NEW },
     { "NUMBERVALUE",            "NUMBERVALUE",          NOID,   NOID,   1,  3,  V, { VR }, FUNCFLAG_MACROCALL_NEW },
     { "PDURATION",              "PDURATION",            NOID,   NOID,   3,  3,  V, { VR }, FUNCFLAG_MACROCALL_NEW },
diff --git a/sc/source/ui/src/scfuncs.src b/sc/source/ui/src/scfuncs.src
index f5166bf..b298d73 100644
--- a/sc/source/ui/src/scfuncs.src
+++ b/sc/source/ui/src/scfuncs.src
@@ -1185,7 +1185,31 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS1
         };
         String 5 // Description of Parameter 2
         {
-            Text [ en-US ] = "Indicates the first day of the week (1 = Sunday, other values = Monday)." ;
+            Text [ en-US ] = "Indicates the first day of the week and when week 1 starts." ;
+        };
+    };
+     // -=*# Resource for function ISOWEEKNUM #*=-
+    Resource SC_OPCODE_ISOWEEKNUM
+    {
+        String 1 // Description
+        {
+            Text [ en-US ] = "Calculates the ISO 8601 calender week for the given date." ;
+        };
+        ExtraData =
+        {
+            0;
+            ID_FUNCTION_GRP_DATETIME;
+            U2S( HID_FUNC_ISOWEEKNUM );
+            1;  0;  0;
+            0;
+        };
+        String 2 // Name of Parameter 1
+        {
+            Text [ en-US ] = "Number" ;
+        };
+        String 3 // Description of Parameter 1
+        {
+            Text [ en-US ] = "The internal number of the date." ;
         };
     };
      // -=*# Resource for function EASTERSUNDAY #*=-


More information about the Libreoffice-commits mailing list