Coverage Report

Created: 2026-09-28 10:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/include/formula/grammar.hxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
11
 *   Licensed to the Apache Software Foundation (ASF) under one or more
12
 *   contributor license agreements. See the NOTICE file distributed
13
 *   with this work for additional information regarding copyright
14
 *   ownership. The ASF licenses this file to you under the Apache
15
 *   License, Version 2.0 (the "License"); you may not use this file
16
 *   except in compliance with the License. You may obtain a copy of
17
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18
 */
19
20
#pragma once
21
22
#include <com/sun/star/sheet/FormulaLanguage.hpp>
23
#include <formula/formuladllapi.h>
24
#include <sal/types.h>
25
26
namespace formula
27
{
28
29
/** Grammars digested by ScCompiler.
30
 */
31
class FORMULA_DLLPUBLIC FormulaGrammar
32
{
33
public:
34
    enum AddressConvention{
35
        CONV_UNSPECIFIED = -1,  /* useful when we want method to choose, must be first */
36
37
        /* elements must be sequential and changes should be reflected in ScCompiler::pCharTables */
38
        CONV_OOO     =  0,  /* 'doc'#sheet.A1:sheet2.B2 */
39
        CONV_ODF,           /* ['doc'#sheet.A1:sheet2.B2] */
40
        CONV_XL_A1,         /* [doc]sheet:sheet2!A1:B2 */
41
        CONV_XL_R1C1,       /* [doc]sheet:sheet2!R1C1:R2C2 */
42
        CONV_XL_OOX,        /* [#]sheet:sheet2!A1:B2 */
43
44
        CONV_LOTUS_A1,      /* external? 3d? A1.B2 <placeholder/> */
45
46
        CONV_LAST,   /* for loops, must always be last */
47
48
        // not a real address convention, a special case for INDIRECT function interpretation
49
        // only -> try using CONV_OOO, failing that CONV_XL_A1
50
        CONV_A1_XL_A1
51
    };
52
53
    //! CONV_UNSPECIFIED is a negative value!
54
    static const int kConventionOffset = - CONV_UNSPECIFIED + 1;
55
    // Room for 32k hypothetical languages plus EXTERNAL.
56
    static const int kConventionShift  = 16;
57
    // Room for 256 reference conventions.
58
    static const int kEnglishBit       = (1 << (kConventionShift + 8));
59
    // Mask off all non-language bits.
60
    static const int kFlagMask         = ~((~unsigned(0)) << kConventionShift);
61
62
    /** Values encoding the formula language plus address reference convention
63
        plus English parsing/formatting
64
     */
65
    //! When adding new values adapt isSupported() below as well.
66
    enum Grammar
67
    {
68
        /// Used only in ScCompiler ctor and in some XML import API context.
69
        GRAM_UNSPECIFIED    = -1,
70
        /// ODFF with default ODF A1 bracketed references.
71
        GRAM_ODFF           = css::sheet::FormulaLanguage::ODFF                 |
72
                                ((CONV_ODF           +
73
                                  kConventionOffset) << kConventionShift)       |
74
                                kEnglishBit,
75
        /// ODF 1.1 with default ODF A1 bracketed references.
76
        GRAM_PODF           = css::sheet::FormulaLanguage::ODF_11               |
77
                                ((CONV_ODF           +
78
                                  kConventionOffset) << kConventionShift)       |
79
                                kEnglishBit,
80
        /// English with default A1 reference style.
81
        GRAM_ENGLISH        = css::sheet::FormulaLanguage::ENGLISH              |
82
                                ((CONV_OOO           +
83
                                  kConventionOffset) << kConventionShift)       |
84
                                kEnglishBit,
85
        /// Native with default A1 reference style.
86
        GRAM_NATIVE         = css::sheet::FormulaLanguage::NATIVE               |
87
                                ((CONV_OOO           +
88
                                  kConventionOffset) << kConventionShift),
89
        /// ODFF with reference style as set in UI, may be A1 or R1C1.
90
        GRAM_ODFF_UI        = css::sheet::FormulaLanguage::ODFF                 |
91
                                ((CONV_UNSPECIFIED   +
92
                                  kConventionOffset) << kConventionShift)       |
93
                                kEnglishBit,
94
        /// ODFF with A1 reference style, unbracketed.
95
        GRAM_ODFF_A1        = css::sheet::FormulaLanguage::ODFF                 |
96
                                ((CONV_OOO           +
97
                                  kConventionOffset) << kConventionShift)       |
98
                                kEnglishBit,
99
        /// ODF 1.1 with reference style as set in UI, may be A1 or R1C1.
100
        GRAM_PODF_UI        = css::sheet::FormulaLanguage::ODF_11               |
101
                                ((CONV_UNSPECIFIED   +
102
                                  kConventionOffset) << kConventionShift)       |
103
                                kEnglishBit,
104
        /// ODF 1.1 with A1 reference style, unbracketed.
105
        GRAM_PODF_A1        = css::sheet::FormulaLanguage::ODF_11               |
106
                                ((CONV_OOO           +
107
                                  kConventionOffset) << kConventionShift)       |
108
                                kEnglishBit,
109
        /// Native with reference style as set in UI, may be A1 or R1C1.
110
        GRAM_NATIVE_UI      = css::sheet::FormulaLanguage::NATIVE               |
111
                                ((CONV_UNSPECIFIED   +
112
                                  kConventionOffset) << kConventionShift),
113
        /// Native with ODF A1 bracketed references. Not very useful but supported.
114
        GRAM_NATIVE_ODF     = css::sheet::FormulaLanguage::NATIVE               |
115
                                ((CONV_ODF           +
116
                                  kConventionOffset) << kConventionShift),
117
        /// Native with Excel A1 reference style.
118
        GRAM_NATIVE_XL_A1   = css::sheet::FormulaLanguage::NATIVE               |
119
                                ((CONV_XL_A1         +
120
                                  kConventionOffset) << kConventionShift),
121
        /// Native with Excel R1C1 reference style.
122
        GRAM_NATIVE_XL_R1C1 = css::sheet::FormulaLanguage::NATIVE               |
123
                                ((CONV_XL_R1C1       +
124
                                  kConventionOffset) << kConventionShift),
125
        /// English with Excel A1 reference style.
126
        GRAM_ENGLISH_XL_A1   = css::sheet::FormulaLanguage::XL_ENGLISH               |
127
                                ((CONV_XL_A1         +
128
                                  kConventionOffset) << kConventionShift)            |
129
                                kEnglishBit,
130
        /// English with Excel R1C1 reference style.
131
        GRAM_ENGLISH_XL_R1C1 = css::sheet::FormulaLanguage::XL_ENGLISH               |
132
                                ((CONV_XL_R1C1       +
133
                                  kConventionOffset) << kConventionShift)            |
134
                                kEnglishBit,
135
        /// English with Excel OOXML reference style.
136
        GRAM_ENGLISH_XL_OOX  = css::sheet::FormulaLanguage::XL_ENGLISH               |
137
                                ((CONV_XL_OOX        +
138
                                  kConventionOffset) << kConventionShift)            |
139
                                kEnglishBit,
140
        /// Excel OOXML with Excel OOXML reference style.
141
        GRAM_OOXML           = css::sheet::FormulaLanguage::OOXML               |
142
                                ((CONV_XL_OOX        +
143
                                  kConventionOffset) << kConventionShift)       |
144
                                kEnglishBit,
145
        /// API English with A1 reference style, unbracketed.
146
        GRAM_API            = css::sheet::FormulaLanguage::API                  |
147
                                ((CONV_OOO           +
148
                                  kConventionOffset) << kConventionShift)       |
149
                                kEnglishBit,
150
        /// Central definition of the default grammar to be used.
151
        GRAM_DEFAULT        = GRAM_NATIVE_UI,
152
153
        /// Central definition of the default storage grammar to be used.
154
        GRAM_STORAGE_DEFAULT = GRAM_ODFF,
155
156
        /** OpCodeMap set by external filter and merged with reference
157
            convention plus English bit on top. Plain value acts as
158
            FormulaLanguage. */
159
        GRAM_EXTERNAL       = (1 << (kConventionShift - 1))
160
    };
161
162
    /// If English parsing/formatting is associated with a grammar.
163
    static bool isEnglish( const Grammar eGrammar )
164
4.29M
    {
165
4.29M
        return (eGrammar & kEnglishBit) != 0;
166
4.29M
    }
167
168
    /** Compatibility helper for old "bCompileEnglish, bCompileXML" API calls
169
        to obtain the new grammar. */
170
    static Grammar mapAPItoGrammar( const bool bEnglish, const bool bXML );
171
172
    static bool isSupported( const Grammar eGrammar );
173
174
    static sal_Int32 extractFormulaLanguage( const Grammar eGrammar )
175
28.7M
    {
176
28.7M
        return eGrammar & kFlagMask;
177
28.7M
    }
178
179
    static AddressConvention extractRefConvention( const Grammar eGrammar )
180
9.50M
    {
181
9.50M
        return static_cast<AddressConvention>(
182
9.50M
                ((eGrammar & ~kEnglishBit) >> kConventionShift) -
183
9.50M
                kConventionOffset);
184
9.50M
    }
185
186
    static Grammar setEnglishBit( const Grammar eGrammar, const bool bEnglish );
187
188
    static Grammar mergeToGrammar( const Grammar eGrammar, const AddressConvention eConv );
189
190
    /// If grammar is of ODF 1.1
191
    static bool isPODF( const Grammar eGrammar )
192
2.63M
    {
193
2.63M
        return extractFormulaLanguage( eGrammar) ==
194
2.63M
            css::sheet::FormulaLanguage::ODF_11;
195
2.63M
    }
196
197
    /// If grammar is of ODFF
198
    static bool isODFF( const Grammar eGrammar )
199
5.18M
    {
200
5.18M
        return extractFormulaLanguage( eGrammar) ==
201
5.18M
            css::sheet::FormulaLanguage::ODFF;
202
5.18M
    }
203
204
    /// If grammar is of OOXML
205
    static bool isOOXML( const Grammar eGrammar )
206
12.1M
    {
207
12.1M
        return extractFormulaLanguage( eGrammar) ==
208
12.1M
            css::sheet::FormulaLanguage::OOXML;
209
12.1M
    }
210
211
    /** If reference convention is OOXML.
212
213
        Note this is not equivalent to isOOXML() as it does not have to be
214
        FormulaLanguage::OOXML but can be Grammar::GRAM_EXTERNAL merged with
215
        AddressConvention::CONV_XL_OOX, which is used by various parts of OOXML
216
        import through the API FormulaParser.
217
     */
218
    static bool isRefConventionOOXML( const Grammar eGrammar )
219
2.30k
    {
220
2.30k
        return extractRefConvention( eGrammar) ==
221
2.30k
            FormulaGrammar::AddressConvention::CONV_XL_OOX;
222
2.30k
    }
223
224
    /// If grammar has an Excel syntax, determined by address convention.
225
    static bool isExcelSyntax( const Grammar eGrammar )
226
177k
    {
227
177k
        AddressConvention eConv = extractRefConvention( eGrammar );
228
177k
        switch (eConv)
229
177k
        {
230
0
            case FormulaGrammar::AddressConvention::CONV_XL_A1:
231
0
            case FormulaGrammar::AddressConvention::CONV_XL_R1C1:
232
10.4k
            case FormulaGrammar::AddressConvention::CONV_XL_OOX:
233
10.4k
                return true;
234
166k
            default:
235
166k
                return false;
236
177k
        }
237
177k
    }
238
239
};
240
241
} // formula
242
243
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */