[Libreoffice-commits] core.git: 8 commits - config_host/config_options_calc.h.in config_host.mk.in configure.ac sc/inc sc/Library_sc.mk sc/source
Kohei Yoshida
kohei.yoshida at collabora.com
Wed Oct 26 03:56:53 UTC 2016
config_host.mk.in | 1
config_host/config_options_calc.h.in | 10 +
configure.ac | 22 +++
sc/Library_sc.mk | 6
sc/inc/formulalogger.hxx | 127 ++++++++++++++++++
sc/source/core/data/formulacell.cxx | 18 ++
sc/source/core/tool/formulalogger.cxx | 238 ++++++++++++++++++++++++++++++++++
7 files changed, 422 insertions(+)
New commits:
commit 9c34797cc98030614b384b6ea0f233d59ae82253
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Tue Oct 25 07:24:40 2016 -0400
Keep loplugin:staticmethods happy.
Change-Id: I45b576a4401d51d204007a8dde3b24617b5a17e9
diff --git a/sc/inc/formulalogger.hxx b/sc/inc/formulalogger.hxx
index 1348c63..10a0155 100644
--- a/sc/inc/formulalogger.hxx
+++ b/sc/inc/formulalogger.hxx
@@ -95,6 +95,7 @@ public:
*/
class FormulaLogger
{
+ bool mbState = false; // Just to avoid loplugin:staticmethods
public:
static FormulaLogger get()
@@ -104,13 +105,15 @@ public:
class GroupScope
{
+ bool mbState = false; // Just to avoid loplugin:staticmethods
public:
- void addMessage( const OUString& /*rMsg*/ ) {}
- void setCalcComplete() {}
+ void addMessage( const OUString& /*rMsg*/ ) { mbState = !mbState; }
+ void setCalcComplete() { mbState = !mbState; }
};
GroupScope enterGroup( const ScDocument& /*rDoc*/, const ScFormulaCell& /*rCell*/ )
{
+ mbState = !mbState;
return GroupScope();
}
};
commit dff4e51f5db23baab368ab7e656ad1b74f2663bd
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Mon Oct 24 18:56:51 2016 -0400
Add configure option --enable-formula-logger to conditionalize it.
Change-Id: I1badbcfa259b22d742e5241bd817ea44769a771e
diff --git a/config_host.mk.in b/config_host.mk.in
index 90c25a6..260acf7 100644
--- a/config_host.mk.in
+++ b/config_host.mk.in
@@ -130,6 +130,7 @@ export ENABLE_DIRECTX=@ENABLE_DIRECTX@
export ENABLE_EOT=@ENABLE_EOT@
export ENABLE_EVOAB2=@ENABLE_EVOAB2@
export ENABLE_FIREBIRD_SDBC=@ENABLE_FIREBIRD_SDBC@
+export ENABLE_FORMULA_LOGGER=@ENABLE_FORMULA_LOGGER@
export ENABLE_GIO=@ENABLE_GIO@
export ENABLE_GRAPHITE=@ENABLE_GRAPHITE@
export ENABLE_ORCUS=@ENABLE_ORCUS@
diff --git a/config_host/config_options_calc.h.in b/config_host/config_options_calc.h.in
new file mode 100644
index 0000000..f369797
--- /dev/null
+++ b/config_host/config_options_calc.h.in
@@ -0,0 +1,10 @@
+/*
+ * General configuration settings for various options specific to Calc.
+ */
+
+#ifndef CONFIG_OPTIONS_CALC_H
+#define CONFIG_OPTIONS_CALC_H
+
+#define ENABLE_FORMULA_LOGGER 0
+
+#endif
diff --git a/configure.ac b/configure.ac
index af07d13..f06ef8e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1515,6 +1515,13 @@ AC_ARG_ENABLE(dconf,
[Disable the dconf configuration backend (enabled by default where
available).]))
+AC_ARG_ENABLE(formula-logger,
+ AS_HELP_STRING(
+ [--enable-formula-logger],
+ [Enable formula logger for logging formula calculation flow in Calc.]
+ )
+)
+
dnl ===================================================================
dnl Optional Packages (--with/without-)
dnl ===================================================================
@@ -12754,6 +12761,20 @@ else
fi
AC_SUBST(MPL_SUBSET)
+dnl ===================================================================
+
+AC_MSG_CHECKING([formula logger])
+ENABLE_FORMULA_LOGGER=
+
+if test "x$enable_formula_logger" = "xyes"; then
+ AC_MSG_RESULT([yes])
+ AC_DEFINE(ENABLE_FORMULA_LOGGER)
+ ENABLE_FORMULA_LOGGER=TRUE
+else
+ AC_MSG_RESULT([no])
+fi
+
+AC_SUBST(ENABLE_FORMULA_LOGGER)
dnl ===================================================================
dnl Setting up the environment.
@@ -12927,6 +12948,7 @@ AC_CONFIG_HEADERS([config_host/config_kde4.h])
AC_CONFIG_HEADERS([config_host/config_oox.h])
AC_CONFIG_HEADERS([config_host/config_opengl.h])
AC_CONFIG_HEADERS([config_host/config_options.h])
+AC_CONFIG_HEADERS([config_host/config_options_calc.h])
AC_CONFIG_HEADERS([config_host/config_test.h])
AC_CONFIG_HEADERS([config_host/config_telepathy.h])
AC_CONFIG_HEADERS([config_host/config_typesizes.h])
diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk
index f3abc81..0e21903 100644
--- a/sc/Library_sc.mk
+++ b/sc/Library_sc.mk
@@ -230,7 +230,6 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
sc/source/core/tool/editutil \
sc/source/core/tool/filtopt \
sc/source/core/tool/formulagroup \
- sc/source/core/tool/formulalogger \
sc/source/core/tool/formulaopt \
sc/source/core/tool/formulaparserpool \
sc/source/core/tool/formularesult \
@@ -671,6 +670,12 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
sc/source/ui/xmlsource/xmlsourcedlg \
))
+ifeq ($(ENABLE_FORMULA_LOGGER),TRUE)
+$(eval $(call gb_Library_add_exception_objects,sc,\
+ sc/source/core/tool/formulalogger \
+))
+endif
+
ifneq (,$(gb_ENABLE_DBGUTIL))
$(eval $(call gb_Library_add_exception_objects,sc,\
sc/source/ui/view/gridwin_dbgutil \
diff --git a/sc/inc/formulalogger.hxx b/sc/inc/formulalogger.hxx
index 144fabf..1348c63 100644
--- a/sc/inc/formulalogger.hxx
+++ b/sc/inc/formulalogger.hxx
@@ -12,11 +12,15 @@
#include <memory>
#include <vector>
+#include <config_options_calc.h>
+
class ScFormulaCell;
class ScDocument;
namespace sc {
+#if ENABLE_FORMULA_LOGGER
+
/**
* Outputs formula calculation log outputs to specified file.
*/
@@ -84,6 +88,35 @@ public:
GroupScope enterGroup( const ScDocument& rDoc, const ScFormulaCell& rCell );
};
+#else
+
+/**
+ * Dummy class with all empty inline methods.
+ */
+class FormulaLogger
+{
+public:
+
+ static FormulaLogger get()
+ {
+ return FormulaLogger();
+ }
+
+ class GroupScope
+ {
+ public:
+ void addMessage( const OUString& /*rMsg*/ ) {}
+ void setCalcComplete() {}
+ };
+
+ GroupScope enterGroup( const ScDocument& /*rDoc*/, const ScFormulaCell& /*rCell*/ )
+ {
+ return GroupScope();
+ }
+};
+
+#endif // ENABLE_FORMULA_LOGGER
+
}
#endif
commit 08086d76f86794963b3ab27168f9516edf7b9d2d
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Sat Oct 22 21:36:22 2016 -0400
Ensure that GroupScope can only be instantiated by FormulaLogger.
And also annotate the class a bit.
Change-Id: I7544e49991778be36a9214851f3d7add4bfef626
diff --git a/sc/inc/formulalogger.hxx b/sc/inc/formulalogger.hxx
index d272ed0..144fabf 100644
--- a/sc/inc/formulalogger.hxx
+++ b/sc/inc/formulalogger.hxx
@@ -17,6 +17,9 @@ class ScDocument;
namespace sc {
+/**
+ * Outputs formula calculation log outputs to specified file.
+ */
class FormulaLogger
{
std::unique_ptr<osl::File> mpLogFile;
@@ -42,6 +45,8 @@ public:
*/
class GroupScope
{
+ friend class FormulaLogger;
+
struct Impl;
std::unique_ptr<Impl> mpImpl;
@@ -50,13 +55,23 @@ public:
GroupScope( const GroupScope& ) = delete;
GroupScope& operator= ( const GroupScope& ) = delete;
- GroupScope( FormulaLogger& rLogger, const OUString& rPrefix, const ScDocument& rDoc, const ScFormulaCell& rCell );
+ private:
+ GroupScope(
+ FormulaLogger& rLogger, const OUString& rPrefix,
+ const ScDocument& rDoc, const ScFormulaCell& rCell );
+ public:
GroupScope( GroupScope&& r );
~GroupScope();
- void addMessage( const OUString& rName );
+ /**
+ * Add an arbitrary message to dump to the log.
+ */
+ void addMessage( const OUString& rMsg );
+ /**
+ * Call this when the group calculation has finished successfullly.
+ */
void setCalcComplete();
};
commit 90b7f35ce3ea8de5cb8a6ad8779c4307f95394d6
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Sat Oct 22 21:28:04 2016 -0400
LIBO_FORMULA_LOG_FILE env var to specify the log file location.
In theory you can either use file:///foo/bar or /foo/bar style of
file path.
And also make sure that we don't crash in case a file is not
specified or the file path is invalid.
Change-Id: Ia1fb11af84f91e678401bde11454522db9893f4c
diff --git a/sc/inc/formulalogger.hxx b/sc/inc/formulalogger.hxx
index d8ce3a4..d272ed0 100644
--- a/sc/inc/formulalogger.hxx
+++ b/sc/inc/formulalogger.hxx
@@ -29,6 +29,8 @@ class FormulaLogger
void write( const OUString& ou );
void write( sal_Int32 n );
+ void sync();
+
void writeNestLevel();
public:
diff --git a/sc/source/core/tool/formulalogger.cxx b/sc/source/core/tool/formulalogger.cxx
index 69b1ef9..c7ae53b 100644
--- a/sc/source/core/tool/formulalogger.cxx
+++ b/sc/source/core/tool/formulalogger.cxx
@@ -16,8 +16,29 @@
#include <sfx2/docfile.hxx>
#include <tools/urlobj.hxx>
+#include <cstdlib>
+
namespace sc {
+namespace {
+
+std::unique_ptr<osl::File> initFile()
+{
+ const char* pPath = std::getenv("LIBO_FORMULA_LOG_FILE");
+ if (!pPath)
+ return nullptr;
+
+ // Support both file:///... and system file path notations.
+ OUString aPath = OUString::createFromAscii(pPath);
+ INetURLObject aURL;
+ aURL.SetSmartURL(aPath);
+ aPath = aURL.GetMainURL(INetURLObject::NO_DECODE);
+
+ return o3tl::make_unique<osl::File>(aPath);
+}
+
+}
+
FormulaLogger& FormulaLogger::get()
{
static FormulaLogger aLogger;
@@ -72,7 +93,7 @@ struct FormulaLogger::GroupScope::Impl
mrLogger.writeAscii(")\n");
- mrLogger.mpLogFile->sync();
+ mrLogger.sync();
--mrLogger.mnNestLevel;
}
@@ -97,8 +118,13 @@ void FormulaLogger::GroupScope::setCalcComplete()
addMessage("calculation performed");
}
-FormulaLogger::FormulaLogger() : mpLogFile(o3tl::make_unique<osl::File>("file:///home/kohei/tmp/formula.log"))
+FormulaLogger::FormulaLogger()
{
+ mpLogFile = initFile();
+
+ if (!mpLogFile)
+ return;
+
osl::FileBase::RC eRC = mpLogFile->open(osl_File_OpenFlag_Write | osl_File_OpenFlag_Create);
if (eRC == osl::FileBase::E_EXIST)
@@ -126,9 +152,8 @@ FormulaLogger::FormulaLogger() : mpLogFile(o3tl::make_unique<osl::File>("file://
return;
}
- sal_uInt64 nBytes;
- mpLogFile->write("---\n", 4, nBytes);
- mpLogFile->sync();
+ writeAscii("---\n");
+ sync();
}
FormulaLogger::~FormulaLogger()
@@ -167,6 +192,14 @@ void FormulaLogger::write( sal_Int32 n )
writeAscii(s.getStr(), s.getLength());
}
+void FormulaLogger::sync()
+{
+ if (!mpLogFile)
+ return;
+
+ mpLogFile->sync();
+}
+
void FormulaLogger::writeNestLevel()
{
// Write the nest level, but keep it only 1-character length to avoid
@@ -176,8 +209,8 @@ void FormulaLogger::writeNestLevel()
else
writeAscii("!");
- writeAscii(":");
- for (sal_Int32 i = 0; i < mnNestLevel; ++i)
+ writeAscii(": ");
+ for (sal_Int32 i = 1; i < mnNestLevel; ++i)
writeAscii(" ");
}
commit 12127e1eaf63fec008cba3fe705e23ba86a704f7
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Sat Oct 22 21:03:30 2016 -0400
Write nest levels in case of nested group calculations.
Change-Id: Ie2a94bf76ab28f792ff5684879365fda81c10e2b
diff --git a/sc/inc/formulalogger.hxx b/sc/inc/formulalogger.hxx
index bc547b9..d8ce3a4 100644
--- a/sc/inc/formulalogger.hxx
+++ b/sc/inc/formulalogger.hxx
@@ -20,14 +20,17 @@ namespace sc {
class FormulaLogger
{
std::unique_ptr<osl::File> mpLogFile;
- OUString maGroupPrefix;
std::vector<OUString> maMessages;
+ sal_Int32 mnNestLevel = 0;
+
void writeAscii( const char* s );
void writeAscii( const char* s, size_t n );
void write( const OUString& ou );
void write( sal_Int32 n );
+ void writeNestLevel();
+
public:
static FormulaLogger& get();
@@ -45,7 +48,8 @@ public:
GroupScope( const GroupScope& ) = delete;
GroupScope& operator= ( const GroupScope& ) = delete;
- GroupScope( FormulaLogger& rLogger, const OUString& rPrefix );
+ GroupScope( FormulaLogger& rLogger, const OUString& rPrefix, const ScDocument& rDoc, const ScFormulaCell& rCell );
+
GroupScope( GroupScope&& r );
~GroupScope();
diff --git a/sc/source/core/tool/formulalogger.cxx b/sc/source/core/tool/formulalogger.cxx
index db51259..69b1ef9 100644
--- a/sc/source/core/tool/formulalogger.cxx
+++ b/sc/source/core/tool/formulalogger.cxx
@@ -16,8 +16,6 @@
#include <sfx2/docfile.hxx>
#include <tools/urlobj.hxx>
-#include <iostream>
-
namespace sc {
FormulaLogger& FormulaLogger::get()
@@ -35,28 +33,54 @@ struct FormulaLogger::GroupScope::Impl
bool mbCalcComplete = false;
- Impl( FormulaLogger& rLogger, const OUString& rPrefix ) :
- mrLogger(rLogger), maPrefix(rPrefix) {}
+ Impl( FormulaLogger& rLogger, const OUString& rPrefix, const ScDocument& rDoc, const ScFormulaCell& rCell ) :
+ mrLogger(rLogger), maPrefix(rPrefix)
+ {
+ ++mrLogger.mnNestLevel;
+
+ sc::TokenStringContext aCxt(&rDoc, rDoc.GetGrammar());
+ OUString aFormula = rCell.GetCode()->CreateString(aCxt, rCell.aPos);
+
+ mrLogger.write(maPrefix);
+ mrLogger.writeNestLevel();
+
+ mrLogger.writeAscii("-- enter (formula='");
+ mrLogger.write(aFormula);
+ mrLogger.writeAscii("', size=");
+ mrLogger.write(rCell.GetSharedLength());
+ mrLogger.writeAscii(")\n");
+ }
~Impl()
{
for (const OUString& rMsg : maMessages)
{
mrLogger.write(maPrefix);
- mrLogger.writeAscii(" * ");
+ mrLogger.writeNestLevel();
+ mrLogger.writeAscii(" * ");
mrLogger.write(rMsg);
mrLogger.writeAscii("\n");
}
mrLogger.write(maPrefix);
- mrLogger.writeAscii(mbCalcComplete ? " * calculation complete\n" : " * exited without calculation\n");
+ mrLogger.writeNestLevel();
+ mrLogger.writeAscii("-- exit (");
+ if (mbCalcComplete)
+ mrLogger.writeAscii("calculation complete");
+ else
+ mrLogger.writeAscii("without calculation");
+
+ mrLogger.writeAscii(")\n");
mrLogger.mpLogFile->sync();
+
+ --mrLogger.mnNestLevel;
}
};
-FormulaLogger::GroupScope::GroupScope( FormulaLogger& rLogger, const OUString& rPrefix ) :
- mpImpl(o3tl::make_unique<Impl>(rLogger, rPrefix)) {}
+FormulaLogger::GroupScope::GroupScope(
+ FormulaLogger& rLogger, const OUString& rPrefix, const ScDocument& rDoc, const ScFormulaCell& rCell ) :
+ mpImpl(o3tl::make_unique<Impl>(rLogger, rPrefix, rDoc, rCell)) {}
FormulaLogger::GroupScope::GroupScope( GroupScope&& r ) : mpImpl(std::move(r.mpImpl)) {}
@@ -69,7 +93,8 @@ void FormulaLogger::GroupScope::addMessage( const OUString& rMsg )
void FormulaLogger::GroupScope::setCalcComplete()
{
- mpImpl->mbCalcComplete;
+ mpImpl->mbCalcComplete = true;
+ addMessage("calculation performed");
}
FormulaLogger::FormulaLogger() : mpLogFile(o3tl::make_unique<osl::File>("file:///home/kohei/tmp/formula.log"))
@@ -142,11 +167,23 @@ void FormulaLogger::write( sal_Int32 n )
writeAscii(s.getStr(), s.getLength());
}
+void FormulaLogger::writeNestLevel()
+{
+ // Write the nest level, but keep it only 1-character length to avoid
+ // messing up the spacing.
+ if (mnNestLevel < 10)
+ write(mnNestLevel);
+ else
+ writeAscii("!");
+
+ writeAscii(":");
+ for (sal_Int32 i = 0; i < mnNestLevel; ++i)
+ writeAscii(" ");
+}
+
FormulaLogger::GroupScope FormulaLogger::enterGroup(
const ScDocument& rDoc, const ScFormulaCell& rCell )
{
- maGroupPrefix = "formula-group: ";
-
// Get the file name if available.
const SfxObjectShell* pShell = rDoc.GetDocumentShell();
const SfxMedium* pMedium = pShell->GetMedium();
@@ -154,22 +191,13 @@ FormulaLogger::GroupScope FormulaLogger::enterGroup(
if (aName.isEmpty())
aName = "-"; // unsaved document.
- maGroupPrefix += aName;
- maGroupPrefix += ": ";
- maGroupPrefix += rCell.aPos.Format(ScRefFlags::VALID | ScRefFlags::TAB_3D, &rDoc, rDoc.GetAddressConvention());
- maGroupPrefix += ": ";
- write(maGroupPrefix);
-
- writeAscii("(formula='");
-
- sc::TokenStringContext aCxt(&rDoc, rDoc.GetGrammar());
- write(rCell.GetCode()->CreateString(aCxt, rCell.aPos));
+ OUString aGroupPrefix = aName;
- writeAscii("', size=");
- write(rCell.GetSharedLength());
- writeAscii(")\n");
+ aGroupPrefix += ": formula-group: ";
+ aGroupPrefix += rCell.aPos.Format(ScRefFlags::VALID | ScRefFlags::TAB_3D, &rDoc, rDoc.GetAddressConvention());
+ aGroupPrefix += ": ";
- return GroupScope(*this, maGroupPrefix);
+ return GroupScope(*this, aGroupPrefix, rDoc, rCell);
}
}
commit 662652d864c6d26096cfc7f650d80d1e80235bca
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Sat Oct 22 19:54:37 2016 -0400
Use a singleton pattern here.
Change-Id: I45e8bcdb4ee2717ac7e223e68e0c03da9473db5b
diff --git a/sc/inc/formulalogger.hxx b/sc/inc/formulalogger.hxx
index 581a2eb..bc547b9 100644
--- a/sc/inc/formulalogger.hxx
+++ b/sc/inc/formulalogger.hxx
@@ -30,6 +30,8 @@ class FormulaLogger
public:
+ static FormulaLogger& get();
+
/**
* This class is only moveable.
*/
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index f5c82c4..7f97e26 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -215,13 +215,6 @@ struct DebugCalculationStacker
namespace {
-
-sc::FormulaLogger& getLogger()
-{
- static sc::FormulaLogger aLogger;
- return aLogger;
-}
-
// More or less arbitrary, of course all recursions must fit into available
// stack space (which is what on all systems we don't know yet?). Choosing a
// lower value may be better than trying a much higher value that also isn't
@@ -4038,7 +4031,7 @@ bool ScFormulaCell::InterpretFormulaGroup()
if (!mxGroup || !pCode)
return false;
- auto aScope = getLogger().enterGroup(*pDocument, *this);
+ auto aScope = sc::FormulaLogger::get().enterGroup(*pDocument, *this);
if (mxGroup->meCalcState == sc::GroupCalcDisabled)
{
diff --git a/sc/source/core/tool/formulalogger.cxx b/sc/source/core/tool/formulalogger.cxx
index a9ea3ba..db51259 100644
--- a/sc/source/core/tool/formulalogger.cxx
+++ b/sc/source/core/tool/formulalogger.cxx
@@ -20,6 +20,12 @@
namespace sc {
+FormulaLogger& FormulaLogger::get()
+{
+ static FormulaLogger aLogger;
+ return aLogger;
+}
+
struct FormulaLogger::GroupScope::Impl
{
FormulaLogger& mrLogger;
commit 28a11eee99a0d20566c26ad285e81eac7b7badd6
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Fri Oct 21 22:43:32 2016 -0400
Have the logger instantiate on first use.
Change-Id: Ia2e3c011a66030aafa479f3ea47dcc1fb0c5e8be
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index a56e128..f5c82c4 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -215,7 +215,12 @@ struct DebugCalculationStacker
namespace {
-sc::FormulaLogger aLogger;
+
+sc::FormulaLogger& getLogger()
+{
+ static sc::FormulaLogger aLogger;
+ return aLogger;
+}
// More or less arbitrary, of course all recursions must fit into available
// stack space (which is what on all systems we don't know yet?). Choosing a
@@ -4033,7 +4038,7 @@ bool ScFormulaCell::InterpretFormulaGroup()
if (!mxGroup || !pCode)
return false;
- auto aScope = aLogger.enterGroup(*pDocument, *this);
+ auto aScope = getLogger().enterGroup(*pDocument, *this);
if (mxGroup->meCalcState == sc::GroupCalcDisabled)
{
commit 3ab685241af77f6361b694b06dde6b6c709956e1
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Wed Oct 19 22:28:26 2016 -0400
Initial take on group formula logging.
For now, this logger only logs group formula calculations.
Change-Id: Idab3cf58f8d9e5fd24fc9f7498d55e385ca93ca7
diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk
index 0aa859e..f3abc81 100644
--- a/sc/Library_sc.mk
+++ b/sc/Library_sc.mk
@@ -230,6 +230,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
sc/source/core/tool/editutil \
sc/source/core/tool/filtopt \
sc/source/core/tool/formulagroup \
+ sc/source/core/tool/formulalogger \
sc/source/core/tool/formulaopt \
sc/source/core/tool/formulaparserpool \
sc/source/core/tool/formularesult \
diff --git a/sc/inc/formulalogger.hxx b/sc/inc/formulalogger.hxx
new file mode 100644
index 0000000..581a2eb
--- /dev/null
+++ b/sc/inc/formulalogger.hxx
@@ -0,0 +1,68 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_SC_INC_FORMULALOGGER_HXX
+#define INCLUDED_SC_INC_FORMULALOGGER_HXX
+
+#include <osl/file.hxx>
+#include <memory>
+#include <vector>
+
+class ScFormulaCell;
+class ScDocument;
+
+namespace sc {
+
+class FormulaLogger
+{
+ std::unique_ptr<osl::File> mpLogFile;
+ OUString maGroupPrefix;
+ std::vector<OUString> maMessages;
+
+ void writeAscii( const char* s );
+ void writeAscii( const char* s, size_t n );
+ void write( const OUString& ou );
+ void write( sal_Int32 n );
+
+public:
+
+ /**
+ * This class is only moveable.
+ */
+ class GroupScope
+ {
+ struct Impl;
+ std::unique_ptr<Impl> mpImpl;
+
+ public:
+ GroupScope() = delete;
+ GroupScope( const GroupScope& ) = delete;
+ GroupScope& operator= ( const GroupScope& ) = delete;
+
+ GroupScope( FormulaLogger& rLogger, const OUString& rPrefix );
+ GroupScope( GroupScope&& r );
+ ~GroupScope();
+
+ void addMessage( const OUString& rName );
+
+ void setCalcComplete();
+ };
+
+ FormulaLogger( const FormulaLogger& ) = delete;
+ FormulaLogger& operator= ( const FormulaLogger& ) = delete;
+
+ FormulaLogger();
+ ~FormulaLogger();
+
+ GroupScope enterGroup( const ScDocument& rDoc, const ScFormulaCell& rCell );
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index b95417b..a56e128 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -61,6 +61,7 @@
#include <listenerquery.hxx>
#include <listenerqueryids.hxx>
#include <grouparealistener.hxx>
+#include <formulalogger.hxx>
#if HAVE_FEATURE_OPENCL
#include <opencl/openclwrapper.hxx>
@@ -214,6 +215,8 @@ struct DebugCalculationStacker
namespace {
+sc::FormulaLogger aLogger;
+
// More or less arbitrary, of course all recursions must fit into available
// stack space (which is what on all systems we don't know yet?). Choosing a
// lower value may be better than trying a much higher value that also isn't
@@ -4030,18 +4033,25 @@ bool ScFormulaCell::InterpretFormulaGroup()
if (!mxGroup || !pCode)
return false;
+ auto aScope = aLogger.enterGroup(*pDocument, *this);
+
if (mxGroup->meCalcState == sc::GroupCalcDisabled)
+ {
+ aScope.addMessage("group calc disabled");
return false;
+ }
if (GetWeight() < ScInterpreter::GetGlobalConfig().mnOpenCLMinimumFormulaGroupSize)
{
mxGroup->meCalcState = sc::GroupCalcDisabled;
+ aScope.addMessage("group length below minimum threshold");
return false;
}
if (cMatrixFlag != MM_NONE)
{
mxGroup->meCalcState = sc::GroupCalcDisabled;
+ aScope.addMessage("matrix skipped");
return false;
}
@@ -4055,11 +4065,15 @@ bool ScFormulaCell::InterpretFormulaGroup()
case FormulaVectorUnknown:
default:
// Not good.
+ aScope.addMessage("group calc disabled due to vector state");
return false;
}
if (!ScCalcConfig::isOpenCLEnabled() && !ScCalcConfig::isSwInterpreterEnabled())
+ {
+ aScope.addMessage("opencl not enabled");
return false;
+ }
// Guard against endless recursion of Interpret() calls, for this to work
// ScFormulaCell::InterpretFormulaGroup() must never be called through
@@ -4126,6 +4140,7 @@ bool ScFormulaCell::InterpretFormulaGroup()
xGroup->mpCode = nullptr;
}
+ aScope.addMessage("group token conversion failed");
return false;
}
@@ -4133,6 +4148,7 @@ bool ScFormulaCell::InterpretFormulaGroup()
// generate them.
xGroup->meCalcState = mxGroup->meCalcState = sc::GroupCalcRunning;
sc::FormulaGroupInterpreter *pInterpreter = sc::FormulaGroupInterpreter::getStatic();
+
if (pInterpreter == nullptr ||
!pInterpreter->interpret(*pDocument, xGroup->mpTopCell->aPos, xGroup, aCode))
{
@@ -4147,8 +4163,12 @@ bool ScFormulaCell::InterpretFormulaGroup()
xGroup->mpCode = nullptr;
}
+ aScope.addMessage("group interpretation unsuccessful");
return false;
}
+
+ aScope.setCalcComplete();
+
if (nNumParts > 1)
{
xGroup->mpTopCell = nullptr;
diff --git a/sc/source/core/tool/formulalogger.cxx b/sc/source/core/tool/formulalogger.cxx
new file mode 100644
index 0000000..a9ea3ba
--- /dev/null
+++ b/sc/source/core/tool/formulalogger.cxx
@@ -0,0 +1,171 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <formulalogger.hxx>
+#include <formulacell.hxx>
+#include <tokenarray.hxx>
+#include <document.hxx>
+#include <tokenstringcontext.hxx>
+
+#include <o3tl/make_unique.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/docfile.hxx>
+#include <tools/urlobj.hxx>
+
+#include <iostream>
+
+namespace sc {
+
+struct FormulaLogger::GroupScope::Impl
+{
+ FormulaLogger& mrLogger;
+
+ OUString maPrefix;
+ std::vector<OUString> maMessages;
+
+ bool mbCalcComplete = false;
+
+ Impl( FormulaLogger& rLogger, const OUString& rPrefix ) :
+ mrLogger(rLogger), maPrefix(rPrefix) {}
+
+ ~Impl()
+ {
+ for (const OUString& rMsg : maMessages)
+ {
+ mrLogger.write(maPrefix);
+ mrLogger.writeAscii(" * ");
+ mrLogger.write(rMsg);
+ mrLogger.writeAscii("\n");
+ }
+
+ mrLogger.write(maPrefix);
+ mrLogger.writeAscii(mbCalcComplete ? " * calculation complete\n" : " * exited without calculation\n");
+
+ mrLogger.mpLogFile->sync();
+ }
+};
+
+FormulaLogger::GroupScope::GroupScope( FormulaLogger& rLogger, const OUString& rPrefix ) :
+ mpImpl(o3tl::make_unique<Impl>(rLogger, rPrefix)) {}
+
+FormulaLogger::GroupScope::GroupScope( GroupScope&& r ) : mpImpl(std::move(r.mpImpl)) {}
+
+FormulaLogger::GroupScope::~GroupScope() {}
+
+void FormulaLogger::GroupScope::addMessage( const OUString& rMsg )
+{
+ mpImpl->maMessages.push_back(rMsg);
+}
+
+void FormulaLogger::GroupScope::setCalcComplete()
+{
+ mpImpl->mbCalcComplete;
+}
+
+FormulaLogger::FormulaLogger() : mpLogFile(o3tl::make_unique<osl::File>("file:///home/kohei/tmp/formula.log"))
+{
+ osl::FileBase::RC eRC = mpLogFile->open(osl_File_OpenFlag_Write | osl_File_OpenFlag_Create);
+
+ if (eRC == osl::FileBase::E_EXIST)
+ {
+ eRC = mpLogFile->open(osl_File_OpenFlag_Write);
+
+ if (eRC != osl::FileBase::E_None)
+ {
+ // Failed to open an existing log file.
+ mpLogFile.reset();
+ return;
+ }
+
+ if (mpLogFile->setPos(osl_Pos_End, 0) != osl::FileBase::E_None)
+ {
+ // Failed to set the position to the end of the file.
+ mpLogFile.reset();
+ return;
+ }
+ }
+ else if (eRC != osl::FileBase::E_None)
+ {
+ // Failed to create a new file.
+ mpLogFile.reset();
+ return;
+ }
+
+ sal_uInt64 nBytes;
+ mpLogFile->write("---\n", 4, nBytes);
+ mpLogFile->sync();
+}
+
+FormulaLogger::~FormulaLogger()
+{
+ if (mpLogFile)
+ mpLogFile->close();
+}
+
+void FormulaLogger::writeAscii( const char* s )
+{
+ if (!mpLogFile)
+ return;
+
+ sal_uInt64 nBytes;
+ mpLogFile->write(s, strlen(s), nBytes);
+}
+
+void FormulaLogger::writeAscii( const char* s, size_t n )
+{
+ if (!mpLogFile)
+ return;
+
+ sal_uInt64 nBytes;
+ mpLogFile->write(s, n, nBytes);
+}
+
+void FormulaLogger::write( const OUString& ou )
+{
+ OString s = rtl::OUStringToOString(ou, RTL_TEXTENCODING_UTF8).getStr();
+ writeAscii(s.getStr(), s.getLength());
+}
+
+void FormulaLogger::write( sal_Int32 n )
+{
+ OString s = OString::number(n);
+ writeAscii(s.getStr(), s.getLength());
+}
+
+FormulaLogger::GroupScope FormulaLogger::enterGroup(
+ const ScDocument& rDoc, const ScFormulaCell& rCell )
+{
+ maGroupPrefix = "formula-group: ";
+
+ // Get the file name if available.
+ const SfxObjectShell* pShell = rDoc.GetDocumentShell();
+ const SfxMedium* pMedium = pShell->GetMedium();
+ OUString aName = pMedium->GetURLObject().GetLastName();
+ if (aName.isEmpty())
+ aName = "-"; // unsaved document.
+
+ maGroupPrefix += aName;
+ maGroupPrefix += ": ";
+ maGroupPrefix += rCell.aPos.Format(ScRefFlags::VALID | ScRefFlags::TAB_3D, &rDoc, rDoc.GetAddressConvention());
+ maGroupPrefix += ": ";
+ write(maGroupPrefix);
+
+ writeAscii("(formula='");
+
+ sc::TokenStringContext aCxt(&rDoc, rDoc.GetGrammar());
+ write(rCell.GetCode()->CreateString(aCxt, rCell.aPos));
+
+ writeAscii("', size=");
+ write(rCell.GetSharedLength());
+ writeAscii(")\n");
+
+ return GroupScope(*this, maGroupPrefix);
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
More information about the Libreoffice-commits
mailing list