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  // SAL _DEBUG(__FILE__ ":" << __LINE__ << ": ScCalcConfig::ScCalcConfig(): " << *this);
100 }
101 
103 {
104  // Keep in order of opcode value, is that clearest? (Random order,
105  // at least, would make no sense at all.)
106  static const OpCodeSet pDefaultOpenCLSubsetOpCodes(new o3tl::sorted_vector<OpCode>({
107  ocAdd,
108  ocSub,
109  ocNegSub,
110  ocMul,
111  ocDiv,
112  ocPow,
113  ocRandom,
114  ocSin,
115  ocCos,
116  ocTan,
117  ocArcTan,
118  ocExp,
119  ocLn,
120  ocSqrt,
122  ocSNormInv,
123  ocRound,
124  ocPower,
125  ocSumProduct,
126  ocMin,
127  ocMax,
128  ocSum,
129  ocProduct,
130  ocAverage,
131  ocCount,
132  ocVar,
133  ocNormDist,
134  ocVLookup,
135  ocCorrel,
136  ocCovar,
137  ocPearson,
138  ocSlope,
139  ocSumIfs}));
140 
141  // Note that these defaults better be kept in sync with those in
142  // officecfg/registry/schema/org/openoffice/Office/Calc.xcs.
143  // Crazy.
144  mbOpenCLSubsetOnly = true;
145  mbOpenCLAutoSelect = true;
147  mpOpenCLSubsetOpCodes = pDefaultOpenCLSubsetOpCodes;
148 }
149 
151 {
152  *this = ScCalcConfig();
153 }
154 
156 {
157  // String conversion options are per document.
160  // INDIRECT ref syntax is per document.
163 }
164 
166 {
167  meStringRefAddressSyntax = eConv;
168  mbHasStringRefSyntax = true;
169 }
170 
172 {
182 }
183 
185 {
186  return !operator==(r);
187 }
188 
190 {
191  OUStringBuffer result(256);
192  formula::FormulaCompiler aCompiler;
193  formula::FormulaCompiler::OpCodeMapPtr pOpCodeMap(aCompiler.GetOpCodeMap(css::sheet::FormulaLanguage::ENGLISH));
194 
195  for (auto i = rOpCodes->begin(); i != rOpCodes->end(); ++i)
196  {
197  if (i != rOpCodes->begin())
198  result.append(';');
199  result.append(pOpCodeMap->getSymbol(*i));
200  }
201 
202  return result.toString();
203 }
204 
205 ScCalcConfig::OpCodeSet ScStringToOpCodeSet(std::u16string_view rOpCodes)
206 {
207  ScCalcConfig::OpCodeSet result = std::make_shared<o3tl::sorted_vector< OpCode >>();
208  formula::FormulaCompiler aCompiler;
209  formula::FormulaCompiler::OpCodeMapPtr pOpCodeMap(aCompiler.GetOpCodeMap(css::sheet::FormulaLanguage::ENGLISH));
210 
211  const formula::OpCodeHashMap& rHashMap(pOpCodeMap->getHashMap());
212 
213  sal_Int32 fromIndex(0);
214  sal_Int32 semicolon;
215  OUString s(OUString::Concat(rOpCodes) + ";");
216 
217  while ((semicolon = s.indexOf(';', fromIndex)) >= 0)
218  {
219  if (semicolon > fromIndex)
220  {
221  OUString element(s.copy(fromIndex, semicolon - fromIndex));
222  sal_Int32 n = element.toInt32();
223  if (n > 0 || (n == 0 && element == "0"))
224  result->insert(static_cast<OpCode>(n));
225  else
226  {
227  auto opcode(rHashMap.find(element));
228  if (opcode != rHashMap.end())
229  result->insert(opcode->second);
230  else
231  SAL_WARN("sc.opencl", "Unrecognized OpCode " << element << " in OpCode set string");
232  }
233  }
234  fromIndex = semicolon+1;
235  }
236  // HACK: Both unary and binary minus have the same string but different opcodes.
237  if( result->find( ocSub ) != result->end())
238  result->insert( ocNegSub );
239  return result;
240 }
241 
242 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
ocSqrt
void setOpenCLConfigToDefault()
Definition: calcconfig.cxx:102
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:189
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:155
ocSumIfs
ScCalcConfig::OpCodeSet ScStringToOpCodeSet(std::u16string_view rOpCodes)
Definition: calcconfig.cxx:205
ocPower
int i
OpCodeSet mpOpenCLSubsetOpCodes
Definition: calcconfig.hxx:69
ocMul
ocSub
ocSlope
bool operator!=(const ScCalcConfig &r) const
Definition: calcconfig.cxx:184
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
#define LOCALE
Definition: vbaformat.cxx:57
ocAdd
bool operator==(const ScCalcConfig &r) const
Definition: calcconfig.cxx:171
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:165
ocSum
std::unordered_map< OUString, OpCode > OpCodeHashMap