1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
13 #include <formula/FormulaCompiler.hxx>
14 #include <formula/grammar.hxx>
15 #include <formula/opcode.hxx>
16 #include <rtl/ustring.hxx>
17 #include <sfx2/objsh.hxx>
19 #include "calcconfig.hxx"
20 #include "compiler.hxx"
23 ScCalcConfig::ScCalcConfig() :
24 meStringRefAddressSyntax(formula::FormulaGrammar::CONV_UNSPECIFIED
),
25 meStringConversion(StringConversion::LOCALE
), // old LibreOffice behavior
26 mbEmptyStringAsZero(false),
27 mbHasStringRefSyntax(false)
29 setOpenCLConfigToDefault();
31 // SAL _DEBUG(__FILE__ ":" << __LINE__ << ": ScCalcConfig::ScCalcConfig(): " << *this);
34 void ScCalcConfig::setOpenCLConfigToDefault()
36 // Note that these defaults better be kept in sync with those in
37 // officecfg/registry/schema/org/openoffice/Office/Calc.xcs.
39 mbOpenCLSubsetOnly
= true;
40 mbOpenCLAutoSelect
= true;
41 mnOpenCLMinimumFormulaGroupSize
= 100;
43 // Keep in order of opcode value, is that clearest? (Random order,
44 // at least, would make no sense at all.)
45 maOpenCLSubsetOpCodes
.insert(ocAdd
);
46 maOpenCLSubsetOpCodes
.insert(ocSub
);
47 maOpenCLSubsetOpCodes
.insert(ocMul
);
48 maOpenCLSubsetOpCodes
.insert(ocDiv
);
49 maOpenCLSubsetOpCodes
.insert(ocRandom
);
50 maOpenCLSubsetOpCodes
.insert(ocSin
);
51 maOpenCLSubsetOpCodes
.insert(ocCos
);
52 maOpenCLSubsetOpCodes
.insert(ocTan
);
53 maOpenCLSubsetOpCodes
.insert(ocArcTan
);
54 maOpenCLSubsetOpCodes
.insert(ocExp
);
55 maOpenCLSubsetOpCodes
.insert(ocLn
);
56 maOpenCLSubsetOpCodes
.insert(ocSqrt
);
57 maOpenCLSubsetOpCodes
.insert(ocStdNormDist
);
58 maOpenCLSubsetOpCodes
.insert(ocSNormInv
);
59 maOpenCLSubsetOpCodes
.insert(ocRound
);
60 maOpenCLSubsetOpCodes
.insert(ocPower
);
61 maOpenCLSubsetOpCodes
.insert(ocSumProduct
);
62 maOpenCLSubsetOpCodes
.insert(ocMin
);
63 maOpenCLSubsetOpCodes
.insert(ocMax
);
64 maOpenCLSubsetOpCodes
.insert(ocSum
);
65 maOpenCLSubsetOpCodes
.insert(ocProduct
);
66 maOpenCLSubsetOpCodes
.insert(ocAverage
);
67 maOpenCLSubsetOpCodes
.insert(ocCount
);
68 maOpenCLSubsetOpCodes
.insert(ocVar
);
69 maOpenCLSubsetOpCodes
.insert(ocNormDist
);
70 maOpenCLSubsetOpCodes
.insert(ocVLookup
);
71 maOpenCLSubsetOpCodes
.insert(ocCorrel
);
72 maOpenCLSubsetOpCodes
.insert(ocCovar
);
73 maOpenCLSubsetOpCodes
.insert(ocPearson
);
74 maOpenCLSubsetOpCodes
.insert(ocSlope
);
75 maOpenCLSubsetOpCodes
.insert(ocSumIfs
);
78 void ScCalcConfig::reset()
80 *this = ScCalcConfig();
83 void ScCalcConfig::MergeDocumentSpecific( const ScCalcConfig
& r
)
85 // String conversion options are per document.
86 meStringConversion
= r
.meStringConversion
;
87 mbEmptyStringAsZero
= r
.mbEmptyStringAsZero
;
88 // INDIRECT ref syntax is per document.
89 meStringRefAddressSyntax
= r
.meStringRefAddressSyntax
;
90 mbHasStringRefSyntax
= r
.mbHasStringRefSyntax
;
93 void ScCalcConfig::SetStringRefSyntax( formula::FormulaGrammar::AddressConvention eConv
)
95 meStringRefAddressSyntax
= eConv
;
96 mbHasStringRefSyntax
= true;
99 bool ScCalcConfig::operator== (const ScCalcConfig
& r
) const
101 return meStringRefAddressSyntax
== r
.meStringRefAddressSyntax
&&
102 meStringConversion
== r
.meStringConversion
&&
103 mbEmptyStringAsZero
== r
.mbEmptyStringAsZero
&&
104 mbHasStringRefSyntax
== r
.mbHasStringRefSyntax
&&
105 mbOpenCLSubsetOnly
== r
.mbOpenCLSubsetOnly
&&
106 mbOpenCLAutoSelect
== r
.mbOpenCLAutoSelect
&&
107 maOpenCLDevice
== r
.maOpenCLDevice
&&
108 mnOpenCLMinimumFormulaGroupSize
== r
.mnOpenCLMinimumFormulaGroupSize
&&
109 maOpenCLSubsetOpCodes
== r
.maOpenCLSubsetOpCodes
&&
113 bool ScCalcConfig::operator!= (const ScCalcConfig
& r
) const
115 return !operator==(r
);
120 OUString
StringConversionToString(ScCalcConfig::StringConversion eConv
)
124 case ScCalcConfig::StringConversion::ILLEGAL
: return OUString("ILLEGAL");
125 case ScCalcConfig::StringConversion::ZERO
: return OUString("ZERO");
126 case ScCalcConfig::StringConversion::UNAMBIGUOUS
: return OUString("UNAMBIGUOUS");
127 case ScCalcConfig::StringConversion::LOCALE
: return OUString("LOCALE");
128 default: return OUString::number((int) eConv
);
132 } // anonymous namespace
134 std::ostream
& operator<<(std::ostream
& rStream
, const ScCalcConfig
& rConfig
)
137 "StringRefAddressSyntax=" << rConfig
.meStringRefAddressSyntax
<< ","
138 "StringConversion=" << StringConversionToString(rConfig
.meStringConversion
) << ","
139 "EmptyStringAsZero=" << (rConfig
.mbEmptyStringAsZero
?"Y":"N") << ","
140 "HasStringRefSyntax=" << (rConfig
.mbHasStringRefSyntax
?"Y":"N") << ","
141 "OpenCLSubsetOnly=" << (rConfig
.mbOpenCLSubsetOnly
?"Y":"N") << ","
142 "OpenCLAutoSelect=" << (rConfig
.mbOpenCLAutoSelect
?"Y":"N") << ","
143 "OpenCLDevice='" << rConfig
.maOpenCLDevice
<< "',"
144 "OpenCLMinimumFormulaGroupSize=" << rConfig
.mnOpenCLMinimumFormulaGroupSize
<< ","
145 "OpenCLSubsetOpCodes={" << ScOpCodeSetToSymbolicString(rConfig
.maOpenCLSubsetOpCodes
) << "},"
150 OUString
ScOpCodeSetToSymbolicString(const ScCalcConfig::OpCodeSet
& rOpCodes
)
152 OUStringBuffer result
;
153 formula::FormulaCompiler aCompiler
;
154 formula::FormulaCompiler::OpCodeMapPtr
pOpCodeMap(aCompiler
.GetOpCodeMap(css::sheet::FormulaLanguage::ENGLISH
));
156 for (auto i
= rOpCodes
.cbegin(); i
!= rOpCodes
.cend(); ++i
)
158 if (i
!= rOpCodes
.cbegin())
160 result
.append(pOpCodeMap
->getSymbol(*i
));
163 return result
.toString();
166 ScCalcConfig::OpCodeSet
ScStringToOpCodeSet(const OUString
& rOpCodes
)
168 ScCalcConfig::OpCodeSet result
;
169 formula::FormulaCompiler aCompiler
;
170 formula::FormulaCompiler::OpCodeMapPtr
pOpCodeMap(aCompiler
.GetOpCodeMap(css::sheet::FormulaLanguage::ENGLISH
));
172 const formula::OpCodeHashMap
*pHashMap(pOpCodeMap
->getHashMap());
174 sal_Int32
fromIndex(0);
176 OUString
s(rOpCodes
+ ";");
178 while ((semicolon
= s
.indexOf(';', fromIndex
)) >= 0)
180 if (semicolon
> fromIndex
)
182 OUString
element(s
.copy(fromIndex
, semicolon
- fromIndex
));
183 sal_Int32 n
= element
.toInt32();
184 if (n
> 0 || (n
== 0 && element
== "0"))
185 result
.insert(static_cast<OpCode
>(n
));
188 auto opcode(pHashMap
->find(element
));
189 if (opcode
!= pHashMap
->end())
190 result
.insert(static_cast<OpCode
>(opcode
->second
));
192 SAL_WARN("sc.opencl", "Unrecognized OpCode " << element
<< " in OpCode set string");
195 fromIndex
= semicolon
+1;
200 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */