LibreOffice Module sc (master)  1
calcconfig.cxx
Go to the documentation of this file.
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 
10 #include <ostream>
11 
13 #include <formula/grammar.hxx>
14 #include <formula/opcode.hxx>
15 #include <rtl/ustring.hxx>
16 #include <sal/log.hxx>
17 #include <unotools/configmgr.hxx>
18 
19 #include <calcconfig.hxx>
20 
22 
24 
26 {
27  static rtl::Reference<ConfigurationListener> xListener(new ConfigurationListener("/org.openoffice.Office.Common/Misc"));
28  return xListener;
29 }
30 
32 {
33  static rtl::Reference<ConfigurationListener> xListener(new ConfigurationListener("/org.openoffice.Office.Calc/Formula/Calculation"));
34  return xListener;
35 }
36 
38 {
39  const char* env = getenv( "SC_FORCE_CALCULATION" );
40  if( env != nullptr )
41  {
42  if( strcmp( env, "opencl" ) == 0 )
43  {
44  SAL_INFO("sc.core.formulagroup", "Forcing calculations to use OpenCL");
46  }
47  if( strcmp( env, "threads" ) == 0 )
48  {
49  SAL_INFO("sc.core.formulagroup", "Forcing calculations to use threads");
51  }
52  if( strcmp( env, "core" ) == 0 )
53  {
54  SAL_INFO("sc.core.formulagroup", "Forcing calculations to use core");
55  return ForceCalculationCore;
56  }
57  SAL_WARN("sc.core.formulagroup", "Unrecognized value of SC_FORCE_CALCULATION");
58  abort();
59  }
60  return ForceCalculationNone;
61 }
62 
64 {
66  return type;
67 }
68 
70 {
72  return false;
74  if( force != ForceCalculationNone )
75  return force == ForceCalculationOpenCL;
76  static comphelper::ConfigurationListenerProperty<bool> gOpenCLEnabled(getMiscListener(), "UseOpenCL");
77  return gOpenCLEnabled.get();
78 }
79 
81 {
83  return false;
85  if( force != ForceCalculationNone )
86  return force == ForceCalculationThreads;
87  static comphelper::ConfigurationListenerProperty<bool> gThreadingEnabled(getFormulaCalculationListener(), "UseThreadedCalculationForFormulaGroups");
88  return gThreadingEnabled.get();
89 }
90 
92  meStringRefAddressSyntax(formula::FormulaGrammar::CONV_UNSPECIFIED),
93  meStringConversion(StringConversion::LOCALE), // old LibreOffice behavior
94  mbEmptyStringAsZero(false),
95  mbHasStringRefSyntax(false)
96 {
98 }
99 
101 {
102  // Keep in order of opcode value, is that clearest? (Random order,
103  // at least, would make no sense at all.)
104  static const OpCodeSet pDefaultOpenCLSubsetOpCodes(new o3tl::sorted_vector<OpCode>({
105  ocAdd,
106  ocSub,
107  ocNegSub,
108  ocMul,
109  ocDiv,
110  ocPow,
111  ocRandom,
112  ocSin,
113  ocCos,
114  ocTan,
115  ocArcTan,
116  ocExp,
117  ocLn,
118  ocSqrt,
120  ocSNormInv,
121  ocRound,
122  ocPower,
123  ocSumProduct,
124  ocMin,
125  ocMax,
126  ocSum,
127  ocProduct,
128  ocAverage,
129  ocCount,
130  ocVar,
131  ocNormDist,
132  ocVLookup,
133  ocCorrel,
134  ocCovar,
135  ocPearson,
136  ocSlope,
137  ocSumIfs}));
138 
139  // Note that these defaults better be kept in sync with those in
140  // officecfg/registry/schema/org/openoffice/Office/Calc.xcs.
141  // Crazy.
142  mbOpenCLSubsetOnly = true;
143  mbOpenCLAutoSelect = true;
145  mpOpenCLSubsetOpCodes = pDefaultOpenCLSubsetOpCodes;
146 }
147 
149 {
150  *this = ScCalcConfig();
151 }
152 
154 {
155  // String conversion options are per document.
158  // INDIRECT ref syntax is per document.
161 }
162 
164 {
165  meStringRefAddressSyntax = eConv;
166  mbHasStringRefSyntax = true;
167 }
168 
170 {
180 }
181 
183 {
184  return !operator==(r);
185 }
186 
188 {
189  OUStringBuffer result(256);
190  formula::FormulaCompiler aCompiler;
191  formula::FormulaCompiler::OpCodeMapPtr pOpCodeMap(aCompiler.GetOpCodeMap(css::sheet::FormulaLanguage::ENGLISH));
192 
193  for (auto i = rOpCodes->begin(); i != rOpCodes->end(); ++i)
194  {
195  if (i != rOpCodes->begin())
196  result.append(';');
197  result.append(pOpCodeMap->getSymbol(*i));
198  }
199 
200  return result.makeStringAndClear();
201 }
202 
203 ScCalcConfig::OpCodeSet ScStringToOpCodeSet(std::u16string_view rOpCodes)
204 {
205  ScCalcConfig::OpCodeSet result = std::make_shared<o3tl::sorted_vector< OpCode >>();
206  formula::FormulaCompiler aCompiler;
207  formula::FormulaCompiler::OpCodeMapPtr pOpCodeMap(aCompiler.GetOpCodeMap(css::sheet::FormulaLanguage::ENGLISH));
208 
209  const formula::OpCodeHashMap& rHashMap(pOpCodeMap->getHashMap());
210 
211  sal_Int32 fromIndex(0);
212  sal_Int32 semicolon;
213  OUString s(OUString::Concat(rOpCodes) + ";");
214 
215  while ((semicolon = s.indexOf(';', fromIndex)) >= 0)
216  {
217  if (semicolon > fromIndex)
218  {
219  OUString element(s.copy(fromIndex, semicolon - fromIndex));
220  sal_Int32 n = element.toInt32();
221  if (n > 0 || (n == 0 && element == "0"))
222  result->insert(static_cast<OpCode>(n));
223  else
224  {
225  auto opcode(rHashMap.find(element));
226  if (opcode != rHashMap.end())
227  result->insert(opcode->second);
228  else
229  SAL_WARN("sc.opencl", "Unrecognized OpCode " << element << " in OpCode set string");
230  }
231  }
232  fromIndex = semicolon+1;
233  }
234  // HACK: Both unary and binary minus have the same string but different opcodes.
235  if( result->find( ocSub ) != result->end())
236  result->insert( ocNegSub );
237  return result;
238 }
239 
240 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
ocSqrt
void setOpenCLConfigToDefault()
Definition: calcconfig.cxx:100
static rtl::Reference< ConfigurationListener > const & getMiscListener()
Definition: calcconfig.cxx:25
static rtl::Reference< ConfigurationListener > const & getFormulaCalculationListener()
Definition: calcconfig.cxx:31
ocVar
ocCos
OUString maOpenCLDevice
Definition: calcconfig.hxx:64
sal_Int64 n
ocExp
ocProduct
static ForceCalculationType getForceCalculationType()
Definition: calcconfig.cxx:63
ocPearson
OUString ScOpCodeSetToSymbolicString(const ScCalcConfig::OpCodeSet &rOpCodes)
Definition: calcconfig.cxx:187
ocCount
ocMin
ocNegSub
ocRound
static bool IsFuzzing()
ocSumProduct
ocSNormInv
std::shared_ptr< o3tl::sorted_vector< OpCode > > OpCodeSet
Definition: calcconfig.hxx:67
bool mbOpenCLSubsetOnly
Definition: calcconfig.hxx:62
StringConversion meStringConversion
Definition: calcconfig.hxx:54
ocCorrel
OpCodeMapPtr GetOpCodeMap(const sal_Int32 nLanguage) const
void MergeDocumentSpecific(const ScCalcConfig &r)
Definition: calcconfig.cxx:153
ocSumIfs
ScCalcConfig::OpCodeSet ScStringToOpCodeSet(std::u16string_view rOpCodes)
Definition: calcconfig.cxx:203
ocPower
int i
OpCodeSet mpOpenCLSubsetOpCodes
Definition: calcconfig.hxx:69
ocMul
ocSub
ocSlope
bool operator!=(const ScCalcConfig &r) const
Definition: calcconfig.cxx:182
ocMax
ocSin
ocVLookup
formula::FormulaGrammar::AddressConvention meStringRefAddressSyntax
Definition: calcconfig.hxx:53
bool mbOpenCLAutoSelect
Definition: calcconfig.hxx:63
static bool isOpenCLEnabled()
Definition: calcconfig.cxx:69
Configuration options for formula interpreter.
Definition: calcconfig.hxx:43
sal_Int32 mnOpenCLMinimumFormulaGroupSize
Definition: calcconfig.hxx:65
ocAdd
bool operator==(const ScCalcConfig &r) const
Definition: calcconfig.cxx:169
constexpr OUStringLiteral LOCALE
Definition: vbaformat.cxx:57
ocArcTan
ocAverage
bool mbHasStringRefSyntax
Definition: calcconfig.hxx:56
ocRandom
#define SAL_INFO(area, stream)
ocLn
ocStdNormDist
ocDiv
ForceCalculationType
Definition: calcconfig.hxx:32
ocPow
Any result
ResultType type
#define SAL_WARN(area, stream)
ocNormDist
std::shared_ptr< const OpCodeMap > OpCodeMapPtr
static ForceCalculationType forceCalculationTypeInit()
Definition: calcconfig.cxx:37
static bool isThreadingEnabled()
Definition: calcconfig.cxx:80
ocCovar
bool mbEmptyStringAsZero
Definition: calcconfig.hxx:55
ocTan
void SetStringRefSyntax(formula::FormulaGrammar::AddressConvention eConv)
Definition: calcconfig.cxx:163
ocSum
std::unordered_map< OUString, OpCode > OpCodeHashMap