[Libreoffice-commits] core.git: Branch 'private/jmux/qt5_fixes' - 21 commits - compilerplugins/clang connectivity/source dbaccess/source icon-themes/colibre icon-themes/colibre_svg officecfg/registry sc/inc sc/qa sc/source solenv/bin solenv/clang-format sw/source vcl/inc vcl/qa vcl/qt5 vcl/source vcl/unx
Jan-Marek Glogowski
glogow at fbihome.de
Fri Jul 6 13:53:52 UTC 2018
Rebased ref, commits from common ancestor:
commit 6df705436a4c03e832c8c21b80796d10d33926e0
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date: Thu Jul 5 18:33:40 2018 +0200
Qt5 rest
Change-Id: I24b37228321ec38db704c32cd7e5164ad230b695
diff --git a/solenv/bin/create-tags b/solenv/bin/create-tags
index c9fd565b823f..6a6082e72fe8 100755
--- a/solenv/bin/create-tags
+++ b/solenv/bin/create-tags
@@ -11,6 +11,15 @@ ctags="ctags $@"
saloptions="-ISAL_DELETED_FUNCTION -ISAL_OVERRIDE -ISAL_FINAL"
omnicppoptions="--c++-kinds=+p --fields=+iaS --extra=+q"
+if [ "$1" = "-e" ]; then
+ tagfile="TAGS"
+else
+ tagfile="tags"
+fi
+
+tmpfile=$(mktemp)
+ctags="$ctags -f $tmpfile"
+
$ctags -h "+.hdl.hrc" --langmap=c:+.hrc.src,c++:+.hdl $saloptions $omnicppoptions \
--languages=-HTML,Java,JavaScript \
--langdef=UNOIDL \
@@ -39,3 +48,5 @@ $ctags -h "+.hdl.hrc" --langmap=c:+.hrc.src,c++:+.hdl $saloptions $omnicppoption
$w/UnoApiHeadersTarget/udkapi/normal \
$w/UnoApiHeadersTarget/offapi/normal \
$w/CustomTarget/officecfg/registry
+
+mv "$tmpfile" "$tagfile"
diff --git a/vcl/qt5/Qt5Graphics_GDI.cxx b/vcl/qt5/Qt5Graphics_GDI.cxx
index 8070b7e2d6c0..5e21626cbaea 100644
--- a/vcl/qt5/Qt5Graphics_GDI.cxx
+++ b/vcl/qt5/Qt5Graphics_GDI.cxx
@@ -446,6 +446,8 @@ void Qt5Graphics::drawBitmap(const SalTwoRect& rPosAry, const SalBitmap& /*rSalB
assert(rPosAry.mnSrcWidth == rPosAry.mnDestWidth);
assert(rPosAry.mnSrcHeight == rPosAry.mnDestHeight);
+
+ assert(false && "Qt5Graphics::drawBitmap");
}
void Qt5Graphics::drawMask(const SalTwoRect& rPosAry, const SalBitmap& /*rSalBitmap*/,
@@ -457,6 +459,8 @@ void Qt5Graphics::drawMask(const SalTwoRect& rPosAry, const SalBitmap& /*rSalBit
assert(rPosAry.mnSrcWidth == rPosAry.mnDestWidth);
assert(rPosAry.mnSrcHeight == rPosAry.mnDestHeight);
+
+ assert(false && "Qt5Graphics::drawMask");
}
std::shared_ptr<SalBitmap> Qt5Graphics::getBitmap(long nX, long nY, long nWidth, long nHeight)
@@ -494,6 +498,7 @@ void Qt5Graphics::invert(long nX, long nY, long nWidth, long nHeight, SalInvert
void Qt5Graphics::invert(sal_uInt32 /*nPoints*/, const SalPoint* /*pPtAry*/, SalInvert /*nFlags*/)
{
+ assert(false && "Qt5Graphics::invert 2");
}
bool Qt5Graphics::drawEPS(long /*nX*/, long /*nY*/, long /*nWidth*/, long /*nHeight*/,
diff --git a/vcl/qt5/Qt5Graphics_Text.cxx b/vcl/qt5/Qt5Graphics_Text.cxx
index 37a0879b0044..be3495fb9f51 100644
--- a/vcl/qt5/Qt5Graphics_Text.cxx
+++ b/vcl/qt5/Qt5Graphics_Text.cxx
@@ -132,6 +132,7 @@ void Qt5Graphics::ClearDevFontCache() {}
bool Qt5Graphics::AddTempDevFont(PhysicalFontCollection*, const OUString& /*rFileURL*/,
const OUString& /*rFontName*/)
{
+ assert(false && "Qt5Graphics::AddTempDevFont");
return false;
}
@@ -148,11 +149,15 @@ const void* Qt5Graphics::GetEmbedFontData(const PhysicalFontFace*, long* /*pData
return nullptr;
}
-void Qt5Graphics::FreeEmbedFontData(const void* /*pData*/, long /*nDataLen*/) {}
+void Qt5Graphics::FreeEmbedFontData(const void* /*pData*/, long /*nDataLen*/)
+{
+ assert(false && "Qt5Graphics::FreeEmbedFontData");
+}
void Qt5Graphics::GetGlyphWidths(const PhysicalFontFace* /*pPFF*/, bool /*bVertical*/,
std::vector<sal_Int32>& /*rWidths*/, Ucs2UIntMap& /*rUnicodeEnc*/)
{
+ assert(false && "Qt5Graphics::GetGlyphWidths");
}
bool Qt5Graphics::GetGlyphBoundRect(const GlyphItem& rGlyph, tools::Rectangle& rRect)
diff --git a/vcl/source/outdev/font.cxx b/vcl/source/outdev/font.cxx
index 318b9ffe116a..a4413defde30 100644
--- a/vcl/source/outdev/font.cxx
+++ b/vcl/source/outdev/font.cxx
@@ -199,7 +199,7 @@ bool OutputDevice::GetFontFeatures(std::vector<vcl::font::Feature>& rFontFeature
FontMetric OutputDevice::GetFontMetric() const
{
FontMetric aMetric;
- if( mbNewFont && !ImplNewFont() )
+ if( !ImplNewFont() )
return aMetric;
LogicalFontInstance* pFontInstance = mpFontInstance.get();
@@ -262,10 +262,8 @@ bool OutputDevice::GetFontCharMap( FontCharMapRef& rxFontCharMap ) const
if( !mpGraphics && !AcquireGraphics() )
return false;
- if( mbNewFont )
- ImplNewFont();
- if( mbInitFont )
- InitFont();
+ ImplNewFont();
+ InitFont();
if( !mpFontInstance )
return false;
@@ -287,10 +285,8 @@ bool OutputDevice::GetFontCapabilities( vcl::FontCapabilities& rFontCapabilities
if( !mpGraphics && !AcquireGraphics() )
return false;
- if( mbNewFont )
- ImplNewFont();
- if( mbInitFont )
- InitFont();
+ ImplNewFont();
+ InitFont();
if( !mpFontInstance )
return false;
@@ -995,28 +991,25 @@ void OutputDevice::ImplInitFontList() const
void OutputDevice::InitFont() const
{
- DBG_TESTSOLARMUTEX();
-
- if (!mpFontInstance)
+ if (!mpFontInstance || !mbInitFont)
return;
- if ( mbInitFont )
- {
- // decide if antialiasing is appropriate
- bool bNonAntialiased(GetAntialiasing() & AntialiasingFlags::DisableText);
- FontSelectPattern aPattern(mpFontInstance->GetFontSelectPattern());
- if (!utl::ConfigManager::IsFuzzing())
- {
- const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
- bNonAntialiased |= bool(rStyleSettings.GetDisplayOptions() & DisplayOptions::AADisable);
- bNonAntialiased |= (int(rStyleSettings.GetAntialiasingMinPixelHeight()) > aPattern.mnHeight);
- }
- aPattern.mbNonAntialiased = bNonAntialiased;
+ DBG_TESTSOLARMUTEX();
- // select font in the device layers
- mpGraphics->SetFont(&aPattern, 0);
- mbInitFont = false;
+ // decide if antialiasing is appropriate
+ bool bNonAntialiased(GetAntialiasing() & AntialiasingFlags::DisableText);
+ FontSelectPattern aPattern(mpFontInstance->GetFontSelectPattern());
+ if (!utl::ConfigManager::IsFuzzing())
+ {
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ bNonAntialiased |= bool(rStyleSettings.GetDisplayOptions() & DisplayOptions::AADisable);
+ bNonAntialiased |= (int(rStyleSettings.GetAntialiasingMinPixelHeight()) > aPattern.mnHeight);
}
+ aPattern.mbNonAntialiased = bNonAntialiased;
+
+ // select font in the device layers
+ mpGraphics->SetFont(&aPattern, 0);
+ mbInitFont = false;
}
bool OutputDevice::ImplNewFont() const
@@ -1055,7 +1048,7 @@ bool OutputDevice::ImplNewFont() const
aSize.setHeight( 1 );
else
aSize.setHeight( (12*mnDPIY)/72 );
- fExactHeight = static_cast<float>(aSize.Height());
+ fExactHeight = static_cast<float>(aSize.Height());
}
// select the default width only when logical width is zero
@@ -1076,8 +1069,9 @@ bool OutputDevice::ImplNewFont() const
return false;
}
- // mark when lower layers need to get involved
mbNewFont = false;
+
+ // mark when lower layers need to get involved
if( bNewFontInstance )
mbInitFont = true;
@@ -1120,14 +1114,13 @@ bool OutputDevice::ImplNewFont() const
}
// calculate text offset depending on TextAlignment
- TextAlign eAlign = maFont.GetAlignment();
- if ( eAlign == ALIGN_BASELINE )
+ switch (maFont.GetAlignment())
{
+ case ALIGN_BASELINE:
mnTextOffX = 0;
mnTextOffY = 0;
- }
- else if ( eAlign == ALIGN_TOP )
- {
+ break;
+ case ALIGN_TOP:
mnTextOffX = 0;
mnTextOffY = +pFontInstance->mxFontMetric->GetAscent() + mnEmphasisAscent;
if ( pFontInstance->mnOrientation )
@@ -1135,9 +1128,8 @@ bool OutputDevice::ImplNewFont() const
Point aOriginPt(0, 0);
aOriginPt.RotateAround( mnTextOffX, mnTextOffY, pFontInstance->mnOrientation );
}
- }
- else // eAlign == ALIGN_BOTTOM
- {
+ break;
+ case ALIGN_BOTTOM:
mnTextOffX = 0;
mnTextOffY = -pFontInstance->mxFontMetric->GetDescent() + mnEmphasisDescent;
if ( pFontInstance->mnOrientation )
@@ -1145,6 +1137,10 @@ bool OutputDevice::ImplNewFont() const
Point aOriginPt(0, 0);
aOriginPt.RotateAround( mnTextOffX, mnTextOffY, pFontInstance->mnOrientation );
}
+ break;
+ case TextAlign_FORCE_EQUAL_SIZE:
+ assert( false && "TextAlign_FORCE_EQUAL_SIZE not implemented for new fonts" );
+ break;
}
mbTextLines = ((maFont.GetUnderline() != LINESTYLE_NONE) && (maFont.GetUnderline() != LINESTYLE_DONTKNOW)) ||
@@ -1427,7 +1423,7 @@ std::unique_ptr<SalLayout> OutputDevice::ImplGlyphFallbackLayout( std::unique_pt
long OutputDevice::GetMinKashida() const
{
- if( mbNewFont && !ImplNewFont() )
+ if( !ImplNewFont() )
return 0;
return ImplDevicePixelToLogicWidth( mpFontInstance->mxFontMetric->GetMinKashida() );
commit 7a71526a66890a5a51c891edfd84659943f381bc
Author: Thorsten Behrens <Thorsten.Behrens at CIB.de>
Date: Thu Mar 1 14:57:58 2018 +0100
WaE: -Wunused-variable
Change-Id: I58f012ddc2c5030b0e3e215b9cab4e89abf06c2b
diff --git a/vcl/inc/unx/x11_cursors/null_curs.h b/vcl/inc/unx/x11_cursors/null_curs.h
index d74b462cba9b..ebeee4e6ffc5 100644
--- a/vcl/inc/unx/x11_cursors/null_curs.h
+++ b/vcl/inc/unx/x11_cursors/null_curs.h
@@ -20,6 +20,5 @@
#define nullcurs_height 4
#define nullcurs_x_hot 2
#define nullcurs_y_hot 2
-static unsigned char nullcurs_bits[] = { 0x00, 0x00, 0x00, 0x00 };
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/unx/x11_cursors/null_mask.h b/vcl/inc/unx/x11_cursors/null_mask.h
index bc23e9c9729b..71f08a94afcf 100644
--- a/vcl/inc/unx/x11_cursors/null_mask.h
+++ b/vcl/inc/unx/x11_cursors/null_mask.h
@@ -18,6 +18,5 @@
*/
#define nullmask_width 4
#define nullmask_height 4
-static unsigned char nullmask_bits[] = { 0x00, 0x00, 0x00, 0x00 };
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/generic/app/saldisp.cxx b/vcl/unx/generic/app/saldisp.cxx
index dff49c8e8b7c..ddce3f81da27 100644
--- a/vcl/unx/generic/app/saldisp.cxx
+++ b/vcl/unx/generic/app/saldisp.cxx
@@ -1494,6 +1494,9 @@ KeySym SalDisplay::GetKeySym( XKeyEvent *pEvent,
}
// Pointer
+static unsigned char nullmask_bits[] = { 0x00, 0x00, 0x00, 0x00 };
+static unsigned char nullcurs_bits[] = { 0x00, 0x00, 0x00, 0x00 };
+
#define MAKE_BITMAP( name ) \
XCreateBitmapFromData( pDisp_, \
DefaultRootWindow( pDisp_ ), \
diff --git a/vcl/unx/gtk/gtkdata.cxx b/vcl/unx/gtk/gtkdata.cxx
index 7c9a3d1e0fbc..689fa071ce5b 100644
--- a/vcl/unx/gtk/gtkdata.cxx
+++ b/vcl/unx/gtk/gtkdata.cxx
@@ -245,6 +245,9 @@ GdkCursor* GtkSalDisplay::getFromXBM( const unsigned char *pBitmap,
&aBlack, &aWhite, nXHot, nYHot);
}
+static unsigned char nullmask_bits[] = { 0x00, 0x00, 0x00, 0x00 };
+static unsigned char nullcurs_bits[] = { 0x00, 0x00, 0x00, 0x00 };
+
#define MAKE_CURSOR( vcl_name, name ) \
case vcl_name: \
pCursor = getFromXBM( name##curs##_bits, name##mask##_bits, \
diff --git a/vcl/unx/gtk3/gtk3gtkdata.cxx b/vcl/unx/gtk3/gtk3gtkdata.cxx
index fd5b47f0b626..024dac2a5014 100644
--- a/vcl/unx/gtk3/gtk3gtkdata.cxx
+++ b/vcl/unx/gtk3/gtk3gtkdata.cxx
@@ -213,7 +213,10 @@ GdkCursor* GtkSalDisplay::getFromXBM( const unsigned char *pBitmap,
return cursor;
}
-#define MAKE_CURSOR( vcl_name, name ) \
+static unsigned char nullmask_bits[] = { 0x00, 0x00, 0x00, 0x00 };
+static unsigned char nullcurs_bits[] = { 0x00, 0x00, 0x00, 0x00 };
+
+#define MAKE_CURSOR( vcl_name, name ) \
case vcl_name: \
pCursor = getFromXBM( name##curs##_bits, name##mask##_bits, \
name##curs_width, name##curs_height, \
commit 8981adda6a24a172245b8cd0dd60e31644e23c75
Author: Vikas <vikasmahato0 at gmail.com>
Date: Tue Jul 3 17:05:36 2018 +0530
Added aggregate functions for external data
- Sum, which returns the sum of values in the column.
- Average, which returns the average of values in the column.
- Min, which returns the minimum of the values in the column.
- Max, which returns the maximum of the values in the column.
Change-Id: I196eb2d367d2f8c50ceec42735f6f56e2067e401
Reviewed-on: https://gerrit.libreoffice.org/56862
Tested-by: Jenkins
Reviewed-by: Markus Mohrhard <markus.mohrhard at googlemail.com>
diff --git a/sc/qa/unit/datatransformation_test.cxx b/sc/qa/unit/datatransformation_test.cxx
index 8cec163eeb43..c011941a6cb7 100644
--- a/sc/qa/unit/datatransformation_test.cxx
+++ b/sc/qa/unit/datatransformation_test.cxx
@@ -35,6 +35,10 @@ public:
void testTextToUpper();
void testTextCapitalize();
void testTextTrim();
+ void testAggregateSum();
+ void testAggregateAverage();
+ void testAggregateMin();
+ void testAggregateMax();
CPPUNIT_TEST_SUITE(ScDataTransformationTest);
CPPUNIT_TEST(testColumnRemove);
@@ -44,6 +48,10 @@ public:
CPPUNIT_TEST(testTextToUpper);
CPPUNIT_TEST(testTextCapitalize);
CPPUNIT_TEST(testTextTrim);
+ CPPUNIT_TEST(testAggregateSum);
+ CPPUNIT_TEST(testAggregateAverage);
+ CPPUNIT_TEST(testAggregateMin);
+ CPPUNIT_TEST(testAggregateMax);
CPPUNIT_TEST_SUITE_END();
private:
@@ -193,6 +201,78 @@ void ScDataTransformationTest::testTextTrim()
CPPUNIT_ASSERT_EQUAL(OUString("Paris"), m_pDoc->GetString(2, 2, 0));
}
+void ScDataTransformationTest::testAggregateSum()
+{
+ m_pDoc->SetValue(2, 0, 0, 2034);
+ m_pDoc->SetValue(2, 1, 0, 2342);
+ m_pDoc->SetValue(2, 2, 0, 57452);
+
+ m_pDoc->SetValue(4, 0, 0, 4829.98);
+ m_pDoc->SetValue(4, 1, 0, 53781.3);
+ m_pDoc->SetValue(4, 2, 0, 9876.4);
+ m_pDoc->SetValue(4, 3, 0, 0);
+
+ sc::AggregateFunction aTransform({2, 4}, sc::AGGREGATE_FUNCTION::SUM);
+ aTransform.Transform(*m_pDoc);
+
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(61828, m_pDoc->GetValue(2, 4, 0), 1e-10);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(68487.68, m_pDoc->GetValue(4, 4, 0), 1e-10);
+}
+
+void ScDataTransformationTest::testAggregateAverage()
+{
+ m_pDoc->SetValue(2, 0, 0, 2034);
+ m_pDoc->SetValue(2, 1, 0, 2342);
+ m_pDoc->SetValue(2, 2, 0, 57453);
+
+ m_pDoc->SetValue(3, 0, 0, 4);
+ m_pDoc->SetValue(3, 1, 0, 4);
+ m_pDoc->SetValue(3, 2, 0, 4);
+
+ sc::AggregateFunction aTransform({2, 3}, sc::AGGREGATE_FUNCTION::AVERAGE);
+ aTransform.Transform(*m_pDoc);
+
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(20609.6666666667, m_pDoc->GetValue(2, 3, 0), 1e-10);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(4, m_pDoc->GetValue(3, 3, 0), 1e-10);
+}
+
+void ScDataTransformationTest::testAggregateMin()
+{
+ m_pDoc->SetValue(2, 0, 0, 2034);
+ m_pDoc->SetValue(2, 1, 0, 2342);
+ m_pDoc->SetValue(2, 2, 0, 57453);
+
+ m_pDoc->SetValue(3, 0, 0, 2034);
+ m_pDoc->SetValue(3, 1, 0, -2342);
+ m_pDoc->SetValue(3, 2, 0, 57453);
+
+ sc::AggregateFunction aTransform({2, 3}, sc::AGGREGATE_FUNCTION::MIN);
+ aTransform.Transform(*m_pDoc);
+
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(2034, m_pDoc->GetValue(2, 3, 0), 1e-10);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(-2342, m_pDoc->GetValue(3, 3, 0), 1e-10);
+}
+
+void ScDataTransformationTest::testAggregateMax()
+{
+ m_pDoc->SetValue(2, 0, 0, 2034);
+ m_pDoc->SetValue(2, 1, 0, 2342);
+ m_pDoc->SetValue(2, 2, 0, 57453);
+ m_pDoc->SetValue(2, 3, 0, -453);
+
+ m_pDoc->SetValue(3, 0, 0, 2034);
+ m_pDoc->SetValue(3, 1, 0, -2342);
+ m_pDoc->SetValue(3, 2, 0, -57453);
+ m_pDoc->SetValue(3, 3, 0, -453);
+
+ sc::AggregateFunction aTransform({2, 3}, sc::AGGREGATE_FUNCTION::MAX);
+ aTransform.Transform(*m_pDoc);
+
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(57453, m_pDoc->GetValue(2, 4, 0), 1e-10);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(2034, m_pDoc->GetValue(3, 4, 0), 1e-10);
+}
+
+
ScDataTransformationTest::ScDataTransformationTest() :
ScBootstrapFixture( "sc/qa/unit/data/dataprovider" ),
m_pDoc(nullptr)
diff --git a/sc/source/ui/dataprovider/datatransformation.cxx b/sc/source/ui/dataprovider/datatransformation.cxx
index 84df313aacdc..fd779bf6587a 100644
--- a/sc/source/ui/dataprovider/datatransformation.cxx
+++ b/sc/source/ui/dataprovider/datatransformation.cxx
@@ -10,6 +10,7 @@
#include <datatransformation.hxx>
#include <document.hxx>
+#include <limits>
namespace sc {
@@ -268,6 +269,103 @@ TransformationType TextTransformation::getTransformationType() const
return TransformationType::TEXT_TRANSFORMATION;
}
+AggregateFunction::AggregateFunction(const std::set<SCCOL>& rColumns, const AGGREGATE_FUNCTION rType):
+ maColumns(rColumns),
+ maType(rType)
+{
+}
+
+void AggregateFunction::Transform(ScDocument& rDoc) const
+{
+ SCROW nEndRow = 0;
+ for (auto& itr : maColumns)
+ {
+ nEndRow = getLastRow(rDoc, itr);
+ }
+
+ for (auto& rCol : maColumns)
+ {
+ switch (maType)
+ {
+ case AGGREGATE_FUNCTION::SUM:
+ {
+ double nSum = 0;
+ for (SCROW nRow = 0; nRow <= nEndRow; ++nRow)
+ {
+ CellType eType;
+ rDoc.GetCellType(rCol, nRow, 0, eType);
+ if (eType == CELLTYPE_VALUE)
+ {
+ double nVal = rDoc.GetValue(rCol, nRow, 0);
+ nSum += nVal;
+ }
+ }
+ rDoc.SetValue(rCol, nEndRow + 1, 0, nSum);
+ }
+ break;
+ case AGGREGATE_FUNCTION::AVERAGE:
+ {
+ double nSum = 0;
+ for (SCROW nRow = 0; nRow <= nEndRow; ++nRow)
+ {
+ CellType eType;
+ rDoc.GetCellType(rCol, nRow, 0, eType);
+ if (eType == CELLTYPE_VALUE)
+ {
+ double nVal = rDoc.GetValue(rCol, nRow, 0);
+ nSum += nVal;
+ }
+ }
+
+ double nAvg = nSum / (nEndRow + 1);
+ rDoc.SetValue(rCol, nEndRow + 1, 0, nAvg);
+ }
+ break;
+ case AGGREGATE_FUNCTION::MIN:
+ {
+ double nMin = std::numeric_limits<double>::max();
+ for (SCROW nRow = 0; nRow <= nEndRow; ++nRow)
+ {
+ CellType eType;
+ rDoc.GetCellType(rCol, nRow, 0, eType);
+ if (eType == CELLTYPE_VALUE)
+ {
+ double nVal = rDoc.GetValue(rCol, nRow, 0);
+ if(nVal < nMin)
+ nMin = nVal;
+ }
+ }
+ rDoc.SetValue(rCol, nEndRow + 1, 0, nMin);
+ }
+ break;
+ case AGGREGATE_FUNCTION::MAX:
+ {
+ double nMax = std::numeric_limits<double>::lowest();
+ for (SCROW nRow = 0; nRow <= nEndRow; ++nRow)
+ {
+ CellType eType;
+ rDoc.GetCellType(rCol, nRow, 0, eType);
+ if (eType == CELLTYPE_VALUE)
+ {
+ double nVal = rDoc.GetValue(rCol, nRow, 0);
+ if(nMax < nVal)
+ nMax = nVal;
+ }
+ }
+ rDoc.SetValue(rCol, nEndRow + 1, 0, nMax);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+TransformationType AggregateFunction::getTransformationType() const
+{
+ return TransformationType::AGGREGATE_FUNCTION;
+}
+
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/inc/datatransformation.hxx b/sc/source/ui/inc/datatransformation.hxx
index 522c039851ae..305e35a3cd54 100644
--- a/sc/source/ui/inc/datatransformation.hxx
+++ b/sc/source/ui/inc/datatransformation.hxx
@@ -27,11 +27,14 @@ enum class TransformationType
SPLIT_TRANSFORMATION,
DELETE_TRANSFORMATION,
SORT_TRANSFORMATION,
- TEXT_TRANSFORMATION
+ TEXT_TRANSFORMATION,
+ AGGREGATE_FUNCTION
};
enum class TEXT_TRANSFORM_TYPE { TO_LOWER, TO_UPPER, CAPITALIZE, TRIM };
+enum class AGGREGATE_FUNCTION { SUM, AVERAGE, MIN, MAX };
+
class SC_DLLPUBLIC DataTransformation
{
protected:
@@ -110,6 +113,17 @@ class SC_DLLPUBLIC TextTransformation : public DataTransformation
virtual TransformationType getTransformationType() const override;
};
+class SC_DLLPUBLIC AggregateFunction : public DataTransformation
+{
+ std::set<SCCOL> maColumns;
+ AGGREGATE_FUNCTION maType;
+
+ public:
+ AggregateFunction(const std::set<SCCOL>& rColumns, const AGGREGATE_FUNCTION rType);
+ virtual void Transform(ScDocument& rDoc) const override;
+ virtual TransformationType getTransformationType() const override;
+};
+
}
#endif
commit c3a732a11c320b98e31dad79f421d4d73f33a15b
Author: Xisco Fauli <xiscofauli at libreoffice.org>
Date: Fri Jul 6 11:01:06 2018 +0200
tdf#118547: Remove lock mark only if password is correct
Change-Id: I9f5731dfaaf9b4cc67e600a8b1c01709e7c9ba99
Reviewed-on: https://gerrit.libreoffice.org/57044
Tested-by: Jenkins
Reviewed-by: Eike Rathke <erack at redhat.com>
diff --git a/sc/source/ui/view/viewfunc.cxx b/sc/source/ui/view/viewfunc.cxx
index 9e29d72da734..a4091418909d 100644
--- a/sc/source/ui/view/viewfunc.cxx
+++ b/sc/source/ui/view/viewfunc.cxx
@@ -2557,10 +2557,11 @@ bool ScViewFunc::Unprotect( SCTAB nTab, const OUString& rPassword )
pDocSh->GetUndoManager()->LeaveListAction();
}
- SetTabProtectionSymbol(nTab, false);
-
if (bChanged)
+ {
+ SetTabProtectionSymbol(nTab, false);
UpdateLayerLocks(); //! broadcast to all views
+ }
return bChanged;
}
commit ec68d58afd53ffd5f0f524503dec607e52385c72
Author: Eike Rathke <erack at redhat.com>
Date: Fri Jul 6 12:15:35 2018 +0200
GetNextPos: deduplicate some nMovX code
Change-Id: I9208e2e0a9eaa27a81ffe1dd7054dffc7ddd75f4
Reviewed-on: https://gerrit.libreoffice.org/57050
Reviewed-by: Eike Rathke <erack at redhat.com>
Tested-by: Eike Rathke <erack at redhat.com>
diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx
index 24e8d62a9b77..f68e8fff8e66 100644
--- a/sc/source/core/data/table1.cxx
+++ b/sc/source/core/data/table1.cxx
@@ -1498,82 +1498,70 @@ void ScTable::GetNextPos( SCCOL& rCol, SCROW& rRow, SCCOL nMovX, SCROW nMovY,
const SCCOL nColCount = nEndCol - nStartCol + 1;
std::unique_ptr<SCROW[]> pNextRows( new SCROW[nColCount]);
const SCCOL nLastCol = aCol.size() - 1;
+ const bool bUp = (nMovX < 0); // Moving left also means moving up in rows.
+ const SCROW nRowAdd = (bUp ? -1 : 1);
sal_uInt16 nWrap = 0;
- if ( nMovX > 0 ) // forward
+ for (SCCOL i = 0; i < nColCount; ++i)
+ pNextRows[i] = (i + nStartCol < nCol) ? (nRow + nRowAdd) : nRow;
+ do
{
- for (SCCOL i = 0; i < nColCount; ++i)
- pNextRows[i] = (i + nStartCol < nCol) ? (nRow+1) : nRow;
- do
+ SCROW nNextRow = pNextRows[nCol - nStartCol] + nRowAdd;
+ if ( bMarked )
+ nNextRow = rMark.GetNextMarked( nCol, nNextRow, bUp );
+ if ( bUnprotected )
+ nNextRow = ( nCol <= nLastCol ) ? aCol[nCol].GetNextUnprotected( nNextRow, bUp ) :
+ aDefaultColAttrArray.GetNextUnprotected( nNextRow, bUp );
+ pNextRows[nCol - nStartCol] = nNextRow;
+
+ if (bUp)
{
- SCROW nNextRow = pNextRows[nCol - nStartCol] + 1;
- if ( bMarked )
- nNextRow = rMark.GetNextMarked( nCol, nNextRow, false );
- if ( bUnprotected )
- nNextRow = ( nCol <= nLastCol ) ? aCol[nCol].GetNextUnprotected( nNextRow, false ) :
- aDefaultColAttrArray.GetNextUnprotected( nNextRow, false );
- pNextRows[nCol - nStartCol] = nNextRow;
-
- SCROW nMinRow = nEndRow + 1;
+ SCROW nMaxRow = nStartRow - 1;
for (SCCOL i = 0; i < nColCount; ++i)
{
- if (pNextRows[i] < nMinRow) // when two equal on the left
+ if (pNextRows[i] >= nMaxRow) // when two equal the right one
{
- nMinRow = pNextRows[i];
+ nMaxRow = pNextRows[i];
nCol = i + nStartCol;
}
}
- nRow = nMinRow;
+ nRow = nMaxRow;
- if ( nRow > nEndRow )
+ if ( nRow < nStartRow )
{
if (++nWrap >= 2)
return;
- nCol = nStartCol;
- nRow = nStartRow;
+ nCol = nEndCol;
+ nRow = nEndRow;
for (SCCOL i = 0; i < nColCount; ++i)
- pNextRows[i] = nStartRow; // do it all over again
+ pNextRows[i] = nEndRow; // do it all over again
}
}
- while ( !ValidNextPos(nCol, nRow, rMark, bMarked, bUnprotected) );
- }
- else // backwards
- {
- for (SCCOL i = 0; i < nColCount; ++i)
- pNextRows[i] = (i + nStartCol > nCol) ? (nRow-1) : nRow;
- do
+ else
{
- SCROW nNextRow = pNextRows[nCol - nStartCol] - 1;
- if ( bMarked )
- nNextRow = rMark.GetNextMarked( nCol, nNextRow, true );
- if ( bUnprotected )
- nNextRow = ( nCol <= nLastCol ) ? aCol[nCol].GetNextUnprotected( nNextRow, true ) :
- aDefaultColAttrArray.GetNextUnprotected( nNextRow, true );
- pNextRows[nCol - nStartCol] = nNextRow;
-
- SCROW nMaxRow = nStartRow - 1;
+ SCROW nMinRow = nEndRow + 1;
for (SCCOL i = 0; i < nColCount; ++i)
{
- if (pNextRows[i] >= nMaxRow) // when two equal on the right
+ if (pNextRows[i] < nMinRow) // when two equal the left one
{
- nMaxRow = pNextRows[i];
+ nMinRow = pNextRows[i];
nCol = i + nStartCol;
}
}
- nRow = nMaxRow;
+ nRow = nMinRow;
- if ( nRow < nStartRow )
+ if ( nRow > nEndRow )
{
if (++nWrap >= 2)
return;
- nCol = nEndCol;
- nRow = nEndRow;
+ nCol = nStartCol;
+ nRow = nStartRow;
for (SCCOL i = 0; i < nColCount; ++i)
- pNextRows[i] = nEndRow; // do it all over again
+ pNextRows[i] = nStartRow; // do it all over again
}
}
- while ( !ValidNextPos(nCol, nRow, rMark, bMarked, bUnprotected) );
}
+ while ( !ValidNextPos(nCol, nRow, rMark, bMarked, bUnprotected) );
}
}
commit d778140cca4c1a0b63531f46ea6c5df716e47b98
Author: Henry Castro <hcastro at collabora.com>
Date: Thu Jul 5 15:28:06 2018 -0400
tdf#118540: LO6.1b2: DOCX crashes when properties...
are opened in print preview mode
Change-Id: Idc64d2b98dff157d28813dd3f90a276f8cacd11f
Reviewed-on: https://gerrit.libreoffice.org/57024
Tested-by: Jenkins
Reviewed-by: Henry Castro <hcastro at collabora.com>
diff --git a/sw/source/uibase/app/docsh2.cxx b/sw/source/uibase/app/docsh2.cxx
index ab4c22a5b718..7c210e6a468d 100644
--- a/sw/source/uibase/app/docsh2.cxx
+++ b/sw/source/uibase/app/docsh2.cxx
@@ -145,7 +145,9 @@ using namespace ::sfx2;
// create DocInfo (virtual)
VclPtr<SfxDocumentInfoDialog> SwDocShell::CreateDocumentInfoDialog(const SfxItemSet &rSet)
{
- VclPtr<SfxDocumentInfoDialog> pDlg = VclPtr<SfxDocumentInfoDialog>::Create(&GetView()->GetViewFrame()->GetWindow(), rSet);
+ SfxViewShell* pViewShell = GetView() ? GetView() : SfxViewShell::Current();
+ vcl::Window* pWindow = pViewShell ? &pViewShell->GetViewFrame()->GetWindow() : nullptr;
+ VclPtr<SfxDocumentInfoDialog> pDlg = VclPtr<SfxDocumentInfoDialog>::Create(pWindow, rSet);
//only with statistics, when this document is being shown, not
//from within the Doc-Manager
SwDocShell* pDocSh = static_cast<SwDocShell*>( SfxObjectShell::Current());
commit ff002524c12471668e63837a804b6006f9136a34
Author: Michael Stahl <Michael.Stahl at cib.de>
Date: Tue May 29 11:28:07 2018 +0200
compilerplugins: try to make these work with icecream
There are some problems here, this should fix one of them: the
getFilename function returns "<stdin>" for spelling locations, because
the input to clang is sort of preprocessed via -frewrite-includes if
icecream is used and the file is built on a remote host (whereas it's
apparently not preprocessed if the file is compiled locally by icecream).
Using getPresumedLoc() uses the #line directives in the preprocessed
input, which avoids the problem but is more expensive, so try to use it
only when necessary.
The getFileEntry(getMainFileID())->getName() pattern will also result
in "<stdin>", but fortunately icecream passes -main-file-name,
which oddly enough isn't used by the SourceManager's spelling locations,
but is available separately via CodeGenOptions.
This builds everything successfully with clang version 6.0.0:
ICECC_PREFERRED_HOST=myremote make check gb_SUPPRESS_TESTS=t
Change-Id: Ic121511683e5302d7b9d85186c8b9c4a5443fa1b
Reviewed-on: https://gerrit.libreoffice.org/54993
Tested-by: Jenkins
Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
diff --git a/compilerplugins/clang/automem.cxx b/compilerplugins/clang/automem.cxx
index 52bfdf43d6b3..4675c02325be 100644
--- a/compilerplugins/clang/automem.cxx
+++ b/compilerplugins/clang/automem.cxx
@@ -51,7 +51,7 @@ bool AutoMem::VisitCXXDeleteExpr(const CXXDeleteExpr* expr)
{
if (ignoreLocation( expr ))
return true;
- StringRef aFileName = compiler.getSourceManager().getFilename(compiler.getSourceManager().getSpellingLoc(expr->getLocStart()));
+ StringRef aFileName = getFileNameOfSpellingLoc(compiler.getSourceManager().getSpellingLoc(expr->getLocStart()));
if (loplugin::hasPathnamePrefix(aFileName, SRCDIR "/include/salhelper/")
|| loplugin::hasPathnamePrefix(aFileName, SRCDIR "/include/osl/")
|| loplugin::hasPathnamePrefix(aFileName, SRCDIR "/salhelper/")
diff --git a/compilerplugins/clang/blockblock.cxx b/compilerplugins/clang/blockblock.cxx
index 065e4572e0e1..bdb7d1361410 100644
--- a/compilerplugins/clang/blockblock.cxx
+++ b/compilerplugins/clang/blockblock.cxx
@@ -28,8 +28,7 @@ public:
virtual void run() override
{
- StringRef fn( compiler.getSourceManager().getFileEntryForID(
- compiler.getSourceManager().getMainFileID())->getName() );
+ StringRef fn(handler.getMainFileName());
if (loplugin::isSamePathname(fn, SRCDIR "/sal/osl/unx/file_misc.cxx"))
return;
diff --git a/compilerplugins/clang/checkunusedparams.cxx b/compilerplugins/clang/checkunusedparams.cxx
index 31dae1c66e61..84f05dca4dab 100644
--- a/compilerplugins/clang/checkunusedparams.cxx
+++ b/compilerplugins/clang/checkunusedparams.cxx
@@ -44,8 +44,7 @@ private:
void CheckUnusedParams::run()
{
- StringRef fn( compiler.getSourceManager().getFileEntryForID(
- compiler.getSourceManager().getMainFileID())->getName() );
+ StringRef fn(handler.getMainFileName());
if (loplugin::hasPathnamePrefix(fn, SRCDIR "/sal/"))
return;
// Taking pointer to function
@@ -200,7 +199,7 @@ bool CheckUnusedParams::VisitFunctionDecl(FunctionDecl const * decl) {
return true;
if (isInUnoIncludeFile(compiler.getSourceManager().getSpellingLoc(canon->getLocation())))
return true;
- StringRef fn = compiler.getSourceManager().getFilename(compiler.getSourceManager().getSpellingLoc(canon->getLocStart()));
+ StringRef fn = getFileNameOfSpellingLoc(compiler.getSourceManager().getSpellingLoc(canon->getLocStart()));
// Some backwards compat magic.
// TODO Can probably be removed, but need to do some checking
if (loplugin::isSamePathname(fn, SRCDIR "/include/sax/fshelper.hxx"))
diff --git a/compilerplugins/clang/constantparam.cxx b/compilerplugins/clang/constantparam.cxx
index 3cbcbc8e4043..efff4ac896d5 100644
--- a/compilerplugins/clang/constantparam.cxx
+++ b/compilerplugins/clang/constantparam.cxx
@@ -62,8 +62,7 @@ public:
virtual void run() override
{
// ignore some files that make clang crash inside EvaluateAsInt
- std::string fn( compiler.getSourceManager().getFileEntryForID(
- compiler.getSourceManager().getMainFileID())->getName() );
+ std::string fn(handler.getMainFileName());
loplugin::normalizeDotDotInFilePath(fn);
if (loplugin::isSamePathname(fn, SRCDIR "/basegfx/source/matrix/b2dhommatrix.cxx")
|| loplugin::isSamePathname(fn, SRCDIR "/basegfx/source/matrix/b3dhommatrix.cxx"))
diff --git a/compilerplugins/clang/constparams.cxx b/compilerplugins/clang/constparams.cxx
index 471da7367dc0..08e6aa2f1dc1 100644
--- a/compilerplugins/clang/constparams.cxx
+++ b/compilerplugins/clang/constparams.cxx
@@ -38,8 +38,7 @@ public:
explicit ConstParams(loplugin::InstantiationData const & data): loplugin::FunctionAddress<ConstParams>(data) {}
virtual void run() override {
- std::string fn( compiler.getSourceManager().getFileEntryForID(
- compiler.getSourceManager().getMainFileID())->getName() );
+ std::string fn(handler.getMainFileName());
loplugin::normalizeDotDotInFilePath(fn);
if (startswith(fn, SRCDIR "/sal/")
|| fn == SRCDIR "/jurt/source/pipe/staticsalhack.cxx"
diff --git a/compilerplugins/clang/convertlong.cxx b/compilerplugins/clang/convertlong.cxx
index b706d7dffaa4..8038b8a6371b 100644
--- a/compilerplugins/clang/convertlong.cxx
+++ b/compilerplugins/clang/convertlong.cxx
@@ -35,9 +35,7 @@ public:
virtual void run() override
{
- std::string fn(compiler.getSourceManager()
- .getFileEntryForID(compiler.getSourceManager().getMainFileID())
- ->getName());
+ std::string fn(handler.getMainFileName());
loplugin::normalizeDotDotInFilePath(fn);
// using sal_uIntPtr as in-between type when converting void* to rtl_TextEncoding
if (fn == SRCDIR "/sal/osl/unx/thread.cxx")
@@ -74,7 +72,7 @@ bool ConvertLong::VisitVarDecl(VarDecl const* varDecl)
{
if (ignoreLocation(varDecl))
return true;
- StringRef fileName{ compiler.getSourceManager().getFilename(varDecl->getLocation()) };
+ StringRef fileName{ getFileNameOfSpellingLoc(varDecl->getLocation()) };
if (loplugin::isSamePathname(fileName, SRCDIR "/include/tools/bigint.hxx"))
return true;
if (loplugin::isSamePathname(fileName, SRCDIR "/include/tools/solar.h"))
diff --git a/compilerplugins/clang/datamembershadow.cxx b/compilerplugins/clang/datamembershadow.cxx
index 6e71ce57a4e7..35c96c6f240f 100644
--- a/compilerplugins/clang/datamembershadow.cxx
+++ b/compilerplugins/clang/datamembershadow.cxx
@@ -44,8 +44,8 @@ bool DataMemberShadow::VisitFieldDecl(FieldDecl const * fieldDecl)
if (ignoreLocation(fieldDecl)) {
return true;
}
- StringRef aFileName = compiler.getSourceManager().getFilename(
- compiler.getSourceManager().getSpellingLoc(fieldDecl->getLocStart()));
+ StringRef aFileName = getFileNameOfSpellingLoc(
+ compiler.getSourceManager().getSpellingLoc(fieldDecl->getLocStart()));
// FIXME complex stuff to fix later
diff --git a/compilerplugins/clang/dyncastvisibility.cxx b/compilerplugins/clang/dyncastvisibility.cxx
index afc500f61f61..6a1d84d91d3e 100644
--- a/compilerplugins/clang/dyncastvisibility.cxx
+++ b/compilerplugins/clang/dyncastvisibility.cxx
@@ -115,7 +115,7 @@ public:
// at least some interesting cases (though it would still not be aggressive enough to
// have found ff570b4b58dbf274d3094d21d974f18b613e9b4b "DocumentSettingsSerializer must
// be SAL_DLLPUBLIC_RTTI for dynamic_cast"):
- auto const file = compiler.getSourceManager().getFilename(
+ auto const file = getFileNameOfSpellingLoc(
compiler.getSourceManager().getSpellingLoc(rdd->getLocation()));
if (loplugin::hasPathnamePrefix(file, SRCDIR "/include/")) {
std::size_t const n1 = std::strlen(SRCDIR "/include/");
@@ -127,10 +127,7 @@ public:
auto prefix = std::string(SRCDIR "/");
prefix += seg;
if (!loplugin::hasPathnamePrefix(
- (compiler.getSourceManager()
- .getFileEntryForID(compiler.getSourceManager().getMainFileID())
- ->getName()),
- prefix))
+ handler.getMainFileName(), prefix))
{
report(
DiagnosticsEngine::Warning,
diff --git a/compilerplugins/clang/expressionalwayszero.cxx b/compilerplugins/clang/expressionalwayszero.cxx
index 6633f138cfb3..0f0eb7a541e6 100644
--- a/compilerplugins/clang/expressionalwayszero.cxx
+++ b/compilerplugins/clang/expressionalwayszero.cxx
@@ -35,8 +35,9 @@ public:
virtual void run() override
{
- std::string fn( compiler.getSourceManager().getFileEntryForID(
- compiler.getSourceManager().getMainFileID())->getName() );
+ // don't use getMainFileID, it may return "<stdin>"
+ std::string fn(handler.getMainFileName());
+
loplugin::normalizeDotDotInFilePath(fn);
// encoding of constant value for binary file format
if (startswith(fn, SRCDIR "/package/source/zipapi/ZipFile.cxx"))
diff --git a/compilerplugins/clang/externandnotdefined.cxx b/compilerplugins/clang/externandnotdefined.cxx
index df5455d0dddf..97dff5a8dfa3 100644
--- a/compilerplugins/clang/externandnotdefined.cxx
+++ b/compilerplugins/clang/externandnotdefined.cxx
@@ -57,7 +57,7 @@ bool ExternAndNotDefined::VisitFunctionDecl(const FunctionDecl * functionDecl) {
{
return true;
}
- StringRef fileName { compiler.getSourceManager().getFilename(functionDecl->getLocation()) };
+ StringRef fileName { getFileNameOfSpellingLoc(functionDecl->getLocation()) };
// the filters use some kind of dynamic loading stunt
if (loplugin::hasPathnamePrefix(fileName, SRCDIR "/filter/qa/")) {
return true;
diff --git a/compilerplugins/clang/fragiledestructor.cxx b/compilerplugins/clang/fragiledestructor.cxx
index f8a0ea50660c..d1bff95ddf72 100644
--- a/compilerplugins/clang/fragiledestructor.cxx
+++ b/compilerplugins/clang/fragiledestructor.cxx
@@ -47,7 +47,7 @@ bool FragileDestructor::TraverseCXXDestructorDecl(CXXDestructorDecl* pCXXDestruc
return RecursiveASTVisitor::TraverseCXXDestructorDecl(pCXXDestructorDecl);
}
// ignore this for now, too tricky for me to work out
- StringRef aFileName = compiler.getSourceManager().getFilename(
+ StringRef aFileName = getFileNameOfSpellingLoc(
compiler.getSourceManager().getSpellingLoc(pCXXDestructorDecl->getLocStart()));
if (loplugin::hasPathnamePrefix(aFileName, SRCDIR "/include/comphelper/")
|| loplugin::hasPathnamePrefix(aFileName, SRCDIR "/include/cppuhelper/")
@@ -87,7 +87,8 @@ bool FragileDestructor::VisitCXXMemberCallExpr(const CXXMemberCallExpr* callExpr
return true;
}
// e.g. osl/thread.hxx and cppuhelper/compbase.hxx
- StringRef aFileName = compiler.getSourceManager().getFilename(compiler.getSourceManager().getSpellingLoc(methodDecl->getLocStart()));
+ StringRef aFileName = getFileNameOfSpellingLoc(
+ compiler.getSourceManager().getSpellingLoc(methodDecl->getLocStart()));
if (loplugin::hasPathnamePrefix(aFileName, SRCDIR "/include/osl/")
|| loplugin::hasPathnamePrefix(aFileName, SRCDIR "/include/comphelper/")
|| loplugin::hasPathnamePrefix(aFileName, SRCDIR "/include/cppuhelper/"))
diff --git a/compilerplugins/clang/memoryvar.cxx b/compilerplugins/clang/memoryvar.cxx
index 17cb2701acd0..590af94b7c7a 100644
--- a/compilerplugins/clang/memoryvar.cxx
+++ b/compilerplugins/clang/memoryvar.cxx
@@ -50,7 +50,7 @@ private:
StringRef MemoryVar::getFilename(SourceLocation loc)
{
SourceLocation spellingLocation = compiler.getSourceManager().getSpellingLoc(loc);
- StringRef name { compiler.getSourceManager().getFilename(spellingLocation) };
+ StringRef name { getFileNameOfSpellingLoc(spellingLocation) };
return name;
}
diff --git a/compilerplugins/clang/nullptr.cxx b/compilerplugins/clang/nullptr.cxx
index bc1f7b505243..ccd5837b226f 100644
--- a/compilerplugins/clang/nullptr.cxx
+++ b/compilerplugins/clang/nullptr.cxx
@@ -233,7 +233,7 @@ bool Nullptr::TraverseLinkageSpecDecl(LinkageSpecDecl * decl) {
bool Nullptr::isInLokIncludeFile(SourceLocation spellingLocation) const {
return loplugin::hasPathnamePrefix(
- compiler.getSourceManager().getFilename(spellingLocation),
+ getFileNameOfSpellingLoc(spellingLocation),
SRCDIR "/include/LibreOfficeKit/");
}
diff --git a/compilerplugins/clang/oncevar.cxx b/compilerplugins/clang/oncevar.cxx
index a8a56f5a7e33..afb1b0fa85e9 100644
--- a/compilerplugins/clang/oncevar.cxx
+++ b/compilerplugins/clang/oncevar.cxx
@@ -83,8 +83,7 @@ public:
virtual void run() override {
// ignore some files with problematic macros
- std::string fn( compiler.getSourceManager().getFileEntryForID(
- compiler.getSourceManager().getMainFileID())->getName() );
+ std::string fn(handler.getMainFileName());
loplugin::normalizeDotDotInFilePath(fn);
// platform-specific stuff
if (fn == SRCDIR "/sal/osl/unx/thread.cxx"
diff --git a/compilerplugins/clang/overrideparam.cxx b/compilerplugins/clang/overrideparam.cxx
index 820127e1343d..10e664c75326 100644
--- a/compilerplugins/clang/overrideparam.cxx
+++ b/compilerplugins/clang/overrideparam.cxx
@@ -43,8 +43,7 @@ private:
void OverrideParam::run()
{
/*
- StringRef fn( compiler.getSourceManager().getFileEntryForID(
- compiler.getSourceManager().getMainFileID())->getName() );
+ StringRef fn(handler.getMainFileName());
if (fn == SRCDIR "/include/svx/checklbx.hxx")
return;
*/
diff --git a/compilerplugins/clang/plugin.cxx b/compilerplugins/clang/plugin.cxx
index 56d40e337bf9..1348c3f0f00f 100644
--- a/compilerplugins/clang/plugin.cxx
+++ b/compilerplugins/clang/plugin.cxx
@@ -215,11 +215,37 @@ const FunctionDecl* Plugin::getParentFunctionDecl( const Stmt* stmt )
return nullptr;
}
+StringRef Plugin::getFileNameOfSpellingLoc(SourceLocation spellingLocation) const
+{
+ static enum { NOINIT, STDIN, GOOD } s_Mode(NOINIT);
+ if (s_Mode == GOOD)
+ {
+ return compiler.getSourceManager().getFilename(spellingLocation);
+ }
+ else if (s_Mode == STDIN
+ || !compiler.getSourceManager().isInMainFile(spellingLocation))
+ {
+ const char* bufferName = compiler.getSourceManager().getPresumedLoc(spellingLocation).getFilename();
+ return bufferName;
+ }
+ else
+ {
+ auto const fn(compiler.getSourceManager().getFilename(spellingLocation));
+ if (!fn.data()) // wtf? happens in sot/source/sdstor/stg.cxx
+ {
+ return fn;
+ }
+#if !defined _WIN32
+ assert(fn.startswith("/") || fn == "<stdin>");
+#endif
+ s_Mode = fn == "<stdin>" ? STDIN : GOOD;
+ return getFileNameOfSpellingLoc(spellingLocation);
+ }
+}
bool Plugin::isInUnoIncludeFile(SourceLocation spellingLocation) const
{
- StringRef name {
- compiler.getSourceManager().getFilename(spellingLocation) };
+ StringRef name{ getFileNameOfSpellingLoc(spellingLocation) };
return compiler.getSourceManager().isInMainFile(spellingLocation)
? (isSamePathname(name, SRCDIR "/cppu/source/cppu/compat.cxx")
|| isSamePathname(name, SRCDIR "/cppuhelper/source/compat.cxx")
diff --git a/compilerplugins/clang/plugin.hxx b/compilerplugins/clang/plugin.hxx
index 5299e7f2eac3..4c4d9a70fcb3 100644
--- a/compilerplugins/clang/plugin.hxx
+++ b/compilerplugins/clang/plugin.hxx
@@ -72,6 +72,9 @@ protected:
const Stmt* getParentStmt( const Stmt* stmt );
Stmt* getParentStmt( Stmt* stmt );
const FunctionDecl* getParentFunctionDecl( const Stmt* stmt );
+
+ /// to check file names against whitelists, so that it works with preprocessed input too
+ StringRef getFileNameOfSpellingLoc(SourceLocation spellingLocation) const;
/**
Checks if the location is inside an UNO file, more specifically, if it forms part of the URE stable interface,
which is not allowed to be changed.
diff --git a/compilerplugins/clang/pluginhandler.cxx b/compilerplugins/clang/pluginhandler.cxx
index b1e789a4a8c5..a4637cd78e6d 100644
--- a/compilerplugins/clang/pluginhandler.cxx
+++ b/compilerplugins/clang/pluginhandler.cxx
@@ -55,9 +55,21 @@ static int pluginCount = 0;
static bool bPluginObjectsCreated = false;
static bool unitTestMode = false;
+StringRef initMainFileName(CompilerInstance& compiler)
+{
+ StringRef const& fn(compiler.getASTContext().getSourceManager().getFileEntryForID(
+ compiler.getASTContext().getSourceManager().getMainFileID())->getName());
+ if (fn == "<stdin>")
+ // stdin means icecream, so we can rely on -main-file-name containing the full path name
+ return compiler.getCodeGenOpts().MainFileName;
+ else
+ // this is always a full path name
+ return fn;
+}
+
PluginHandler::PluginHandler( CompilerInstance& compiler, const std::vector< std::string >& args )
: compiler( compiler )
- , mainFileName(compiler.getASTContext().getSourceManager().getFileEntryForID(compiler.getASTContext().getSourceManager().getMainFileID())->getName())
+ , mainFileName(initMainFileName(compiler))
, rewriter( compiler.getSourceManager(), compiler.getLangOpts())
, scope( "mainfile" )
, warningsAsErrors( false )
diff --git a/compilerplugins/clang/pluginhandler.hxx b/compilerplugins/clang/pluginhandler.hxx
index 0b53d7043f00..1cb405d54d35 100644
--- a/compilerplugins/clang/pluginhandler.hxx
+++ b/compilerplugins/clang/pluginhandler.hxx
@@ -60,6 +60,7 @@ public:
// without corrupting the source
bool checkOverlap(SourceRange range);
void addSourceModification(SourceRange range);
+ StringRef const& getMainFileName() const { return mainFileName; }
private:
void handleOption( const std::string& option );
void createPlugins( std::set< std::string > rewriters );
diff --git a/compilerplugins/clang/refcounting.cxx b/compilerplugins/clang/refcounting.cxx
index 8133e281d8aa..f4e7e8e5929b 100644
--- a/compilerplugins/clang/refcounting.cxx
+++ b/compilerplugins/clang/refcounting.cxx
@@ -507,7 +507,8 @@ bool RefCounting::VisitVarDecl(const VarDecl * varDecl) {
<< varDecl->getSourceRange();
}
if (containsSalhelperReferenceObjectSubclass(varDecl->getType().getTypePtr())) {
- StringRef name { compiler.getSourceManager().getFilename(compiler.getSourceManager().getSpellingLoc(varDecl->getLocation())) };
+ StringRef name { getFileNameOfSpellingLoc(
+ compiler.getSourceManager().getSpellingLoc(varDecl->getLocation())) };
// this is playing games that it believes is safe
if (loplugin::isSamePathname(name, SRCDIR "/stoc/source/security/permissions.cxx"))
return true;
diff --git a/compilerplugins/clang/reservedid.cxx b/compilerplugins/clang/reservedid.cxx
index cfb9a5b35818..e3cb737cf6b5 100644
--- a/compilerplugins/clang/reservedid.cxx
+++ b/compilerplugins/clang/reservedid.cxx
@@ -104,8 +104,7 @@ void ReservedId::run() {
if (d->getKind() == MacroDirective::MD_Define) {
auto loc = d->getLocation();
if (loc.isValid() && !ignoreLocation(loc)) {
- auto file = compiler.getSourceManager()
- .getFilename(loc);
+ auto file = getFileNameOfSpellingLoc(loc);
if (!loplugin::isSamePathname(
file,
SRCDIR
@@ -137,7 +136,7 @@ bool ReservedId::VisitNamedDecl(NamedDecl const * decl) {
if (ignoreLocation(spelLoc)) {
return true;
}
- auto filename = compiler.getSourceManager().getFilename(spelLoc);
+ auto filename = getFileNameOfSpellingLoc(spelLoc);
if (loplugin::hasPathnamePrefix(filename, SRCDIR "/bridges/source/cpp_uno/")
&& filename.endswith("share.hxx"))
{
@@ -268,7 +267,7 @@ ReservedId::Kind ReservedId::determineKind(llvm::StringRef const & id) {
bool ReservedId::isInLokIncludeFile(SourceLocation spellingLocation) const {
return loplugin::hasPathnamePrefix(
- compiler.getSourceManager().getFilename(spellingLocation),
+ getFileNameOfSpellingLoc(spellingLocation),
SRCDIR "/include/LibreOfficeKit/");
}
diff --git a/compilerplugins/clang/salbool.cxx b/compilerplugins/clang/salbool.cxx
index e828dbfcfc55..02cc2f609661 100644
--- a/compilerplugins/clang/salbool.cxx
+++ b/compilerplugins/clang/salbool.cxx
@@ -767,7 +767,7 @@ bool SalBool::TraverseStaticAssertDecl(StaticAssertDecl * decl) {
// inside static_assert in cppu/source/uno/check.cxx:
return
loplugin::isSamePathname(
- compiler.getSourceManager().getFilename(decl->getLocation()),
+ getFileNameOfSpellingLoc(decl->getLocation()),
SRCDIR "/cppu/source/uno/check.cxx")
|| RecursiveASTVisitor::TraverseStaticAssertDecl(decl);
}
@@ -803,7 +803,7 @@ bool SalBool::isInSpecialMainFile(SourceLocation spellingLocation) const {
if (!compiler.getSourceManager().isInMainFile(spellingLocation)) {
return false;
}
- auto f = compiler.getSourceManager().getFilename(spellingLocation);
+ auto f = getFileNameOfSpellingLoc(spellingLocation);
return loplugin::isSamePathname(f, SRCDIR "/cppu/qa/test_any.cxx")
|| loplugin::isSamePathname(f, SRCDIR "/cppu/source/uno/check.cxx");
// TODO: the offset checks
diff --git a/compilerplugins/clang/shouldreturnbool.cxx b/compilerplugins/clang/shouldreturnbool.cxx
index d993bf25f21e..ea9e696674de 100644
--- a/compilerplugins/clang/shouldreturnbool.cxx
+++ b/compilerplugins/clang/shouldreturnbool.cxx
@@ -36,9 +36,7 @@ public:
{
if (!compiler.getLangOpts().CPlusPlus)
return;
- StringRef fn(compiler.getSourceManager()
- .getFileEntryForID(compiler.getSourceManager().getMainFileID())
- ->getName());
+ StringRef fn(handler.getMainFileName());
// functions used as function pointers
if (loplugin::isSamePathname(fn, SRCDIR "/sal/rtl/alloc_cache.cxx"))
return;
diff --git a/compilerplugins/clang/simplifydynamiccast.cxx b/compilerplugins/clang/simplifydynamiccast.cxx
index f305f8cbeaef..eb5d111d11a7 100644
--- a/compilerplugins/clang/simplifydynamiccast.cxx
+++ b/compilerplugins/clang/simplifydynamiccast.cxx
@@ -29,8 +29,7 @@ public:
virtual void run() override
{
- // StringRef fn( compiler.getSourceManager().getFileEntryForID(
- // compiler.getSourceManager().getMainFileID())->getName() );
+ // StringRef fn(handler.getMainFileName());
// if (loplugin::isSamePathname(fn, WORKDIR "/YaccTarget/unoidl/source/sourceprovider-parser.cxx"))
// return;
diff --git a/compilerplugins/clang/staticmethods.cxx b/compilerplugins/clang/staticmethods.cxx
index 50d432081f00..aa1b97e01015 100644
--- a/compilerplugins/clang/staticmethods.cxx
+++ b/compilerplugins/clang/staticmethods.cxx
@@ -60,7 +60,7 @@ bool isDerivedFromTestFixture(const CXXRecordDecl *decl) {
StringRef StaticMethods::getFilename(SourceLocation loc)
{
SourceLocation spellingLocation = compiler.getSourceManager().getSpellingLoc(loc);
- return compiler.getSourceManager().getFilename(spellingLocation);
+ return getFileNameOfSpellingLoc(spellingLocation);
}
bool startsWith(const std::string& rStr, const char* pSubStr) {
diff --git a/compilerplugins/clang/stringconcat.cxx b/compilerplugins/clang/stringconcat.cxx
index f5b8d8c2d2ea..818d8314fa45 100644
--- a/compilerplugins/clang/stringconcat.cxx
+++ b/compilerplugins/clang/stringconcat.cxx
@@ -97,7 +97,7 @@ bool StringConcat::VisitCallExpr(CallExpr const * expr) {
leftLoc = left->getArg(1)->getLocStart();
}
StringRef name {
- compiler.getSourceManager().getFilename(
+ getFileNameOfSpellingLoc(
compiler.getSourceManager().getSpellingLoc(expr->getLocStart())) };
if (loplugin::isSamePathname(
name, SRCDIR "/sal/qa/rtl/strings/test_ostring_concat.cxx")
diff --git a/compilerplugins/clang/stringconstant.cxx b/compilerplugins/clang/stringconstant.cxx
index 0555b20af24a..8c01c9e5c017 100644
--- a/compilerplugins/clang/stringconstant.cxx
+++ b/compilerplugins/clang/stringconstant.cxx
@@ -325,7 +325,8 @@ bool StringConstant::VisitCallExpr(CallExpr const * expr) {
{
// u.equalsIgnoreAsciiCaseAscii("foo") ->
// u.equalsIngoreAsciiCase("foo"):
- auto file = compiler.getSourceManager().getFilename(
+
+ auto file = getFileNameOfSpellingLoc(
compiler.getSourceManager().getSpellingLoc(expr->getLocStart()));
if (loplugin::isSamePathname(
file, SRCDIR "/sal/qa/rtl/strings/test_oustring_compare.cxx"))
@@ -343,7 +344,7 @@ bool StringConstant::VisitCallExpr(CallExpr const * expr) {
{
// u.equalsIgnoreAsciiCaseAsciiL("foo", 3) ->
// u.equalsIngoreAsciiCase("foo"):
- auto file = compiler.getSourceManager().getFilename(
+ auto file = getFileNameOfSpellingLoc(
compiler.getSourceManager().getSpellingLoc(expr->getLocStart()));
if (loplugin::isSamePathname(
file, SRCDIR "/sal/qa/rtl/strings/test_oustring_compare.cxx"))
@@ -710,7 +711,7 @@ bool StringConstant::VisitCallExpr(CallExpr const * expr) {
case 2:
{
// b.append("foo", 3) -> b.append("foo"):
- auto file = compiler.getSourceManager().getFilename(
+ auto file = getFileNameOfSpellingLoc(
compiler.getSourceManager().getSpellingLoc(
expr->getLocStart()));
if (loplugin::isSamePathname(
@@ -1077,8 +1078,7 @@ bool StringConstant::VisitCXXConstructExpr(CXXConstructExpr const * expr) {
if (dc.Operator(OO_Plus).Namespace("rtl")
.GlobalNamespace())
{
- auto file =
- compiler.getSourceManager().getFilename(
+ auto file = getFileNameOfSpellingLoc(
compiler.getSourceManager()
.getSpellingLoc(
expr->getLocStart()));
diff --git a/compilerplugins/clang/stringstatic.cxx b/compilerplugins/clang/stringstatic.cxx
index 00f1c9f6eab1..7fa14c0766c7 100644
--- a/compilerplugins/clang/stringstatic.cxx
+++ b/compilerplugins/clang/stringstatic.cxx
@@ -40,8 +40,7 @@ private:
void StringStatic::run()
{
- StringRef fn( compiler.getSourceManager().getFileEntryForID(
- compiler.getSourceManager().getMainFileID())->getName() );
+ StringRef fn(handler.getMainFileName());
// passing around pointers to global OUString
if (loplugin::hasPathnamePrefix(fn, SRCDIR "/filter/source/svg/"))
return;
diff --git a/compilerplugins/clang/unnecessaryoverride.cxx b/compilerplugins/clang/unnecessaryoverride.cxx
index 338598985289..092decc797fc 100644
--- a/compilerplugins/clang/unnecessaryoverride.cxx
+++ b/compilerplugins/clang/unnecessaryoverride.cxx
@@ -72,8 +72,7 @@ public:
virtual void run() override
{
// ignore some files with problematic macros
- StringRef fn( compiler.getSourceManager().getFileEntryForID(
- compiler.getSourceManager().getMainFileID())->getName() );
+ StringRef fn(handler.getMainFileName());
if (loplugin::isSamePathname(fn, SRCDIR "/sd/source/ui/framework/factories/ChildWindowPane.cxx"))
return;
if (loplugin::isSamePathname(fn, SRCDIR "/forms/source/component/Date.cxx"))
@@ -113,7 +112,8 @@ bool UnnecessaryOverride::VisitCXXMethodDecl(const CXXMethodDecl* methodDecl)
return true;
}
- StringRef aFileName = compiler.getSourceManager().getFilename(compiler.getSourceManager().getSpellingLoc(methodDecl->getLocStart()));
+ StringRef aFileName = getFileNameOfSpellingLoc(
+ compiler.getSourceManager().getSpellingLoc(methodDecl->getLocStart()));
if (isa<CXXDestructorDecl>(methodDecl)
&& !isInUnoIncludeFile(methodDecl))
diff --git a/compilerplugins/clang/unnecessaryparen.cxx b/compilerplugins/clang/unnecessaryparen.cxx
index caeadcac0072..0cad779ca7dd 100644
--- a/compilerplugins/clang/unnecessaryparen.cxx
+++ b/compilerplugins/clang/unnecessaryparen.cxx
@@ -67,8 +67,7 @@ public:
virtual void run() override
{
- StringRef fn( compiler.getSourceManager().getFileEntryForID(
- compiler.getSourceManager().getMainFileID())->getName() );
+ StringRef fn(handler.getMainFileName());
// fixing this, makes the source in the .y files look horrible
if (loplugin::isSamePathname(fn, WORKDIR "/YaccTarget/unoidl/source/sourceprovider-parser.cxx"))
return;
diff --git a/compilerplugins/clang/unoany.cxx b/compilerplugins/clang/unoany.cxx
index db20779746bc..8caa7c2a54cf 100644
--- a/compilerplugins/clang/unoany.cxx
+++ b/compilerplugins/clang/unoany.cxx
@@ -28,7 +28,8 @@ bool UnoAny::VisitCXXOperatorCallExpr(CXXOperatorCallExpr const * expr)
if (ignoreLocation(expr)) {
return true;
}
- StringRef aFileName = compiler.getSourceManager().getFilename(compiler.getSourceManager().getSpellingLoc(expr->getLocStart()));
+ StringRef aFileName = getFileNameOfSpellingLoc(
+ compiler.getSourceManager().getSpellingLoc(expr->getLocStart()));
if (loplugin::isSamePathname(aFileName, SRCDIR "/include/com/sun/star/uno/Any.hxx")) {
return true;
}
diff --git a/compilerplugins/clang/unusedvariablemore.cxx b/compilerplugins/clang/unusedvariablemore.cxx
index ead91586c460..fa2ff366052b 100644
--- a/compilerplugins/clang/unusedvariablemore.cxx
+++ b/compilerplugins/clang/unusedvariablemore.cxx
@@ -63,9 +63,7 @@ static bool startswith(const std::string& rStr, const char* pSubStr)
void UnusedVariableMore::run()
{
- std::string fn(compiler.getSourceManager()
- .getFileEntryForID(compiler.getSourceManager().getMainFileID())
- ->getName());
+ std::string fn(handler.getMainFileName());
loplugin::normalizeDotDotInFilePath(fn);
// ignore QA folders
diff --git a/compilerplugins/clang/useuniqueptr.cxx b/compilerplugins/clang/useuniqueptr.cxx
index 7a3722b785f8..5d8d6c57a2fb 100644
--- a/compilerplugins/clang/useuniqueptr.cxx
+++ b/compilerplugins/clang/useuniqueptr.cxx
@@ -32,9 +32,7 @@ public:
virtual void run() override
{
- std::string fn(compiler.getSourceManager()
- .getFileEntryForID(compiler.getSourceManager().getMainFileID())
- ->getName());
+ std::string fn(handler.getMainFileName());
loplugin::normalizeDotDotInFilePath(fn);
// can't change these because we pass them down to the SfxItemPool stuff
if (fn == SRCDIR "/sc/source/core/data/docpool.cxx")
@@ -249,7 +247,8 @@ void UseUniquePtr::CheckDeleteExpr(const CXXMethodDecl* methodDecl, const CXXDel
if (ignoreLocation(fieldDecl))
return;
// to ignore things like the CPPUNIT macros
- StringRef aFileName = compiler.getSourceManager().getFilename(compiler.getSourceManager().getSpellingLoc(fieldDecl->getLocStart()));
+ StringRef aFileName = getFileNameOfSpellingLoc(
+ compiler.getSourceManager().getSpellingLoc(fieldDecl->getLocStart()));
if (loplugin::hasPathnamePrefix(aFileName, WORKDIR "/"))
return;
// passes and stores pointers to member fields
diff --git a/compilerplugins/clang/vclwidgets.cxx b/compilerplugins/clang/vclwidgets.cxx
index af2b1bf46cdd..84d7ffea6bb2 100644
--- a/compilerplugins/clang/vclwidgets.cxx
+++ b/compilerplugins/clang/vclwidgets.cxx
@@ -239,7 +239,7 @@ bool VCLWidgets::VisitCXXDestructorDecl(const CXXDestructorDecl* pCXXDestructorD
if (!bOk) {
SourceLocation spellingLocation = compiler.getSourceManager().getSpellingLoc(
pCXXDestructorDecl->getLocStart());
- StringRef filename = compiler.getSourceManager().getFilename(spellingLocation);
+ StringRef filename = getFileNameOfSpellingLoc(spellingLocation);
if ( !(loplugin::isSamePathname(filename, SRCDIR "/vcl/source/window/window.cxx"))
&& !(loplugin::isSamePathname(filename, SRCDIR "/vcl/source/gdi/virdev.cxx"))
&& !(loplugin::isSamePathname(filename, SRCDIR "/vcl/qa/cppunit/lifecycle.cxx")) )
@@ -278,7 +278,7 @@ void VCLWidgets::checkAssignmentForVclPtrToRawConversion(const SourceLocation& s
if (!rhs) {
return;
}
- StringRef filename = compiler.getSourceManager().getFilename(spellingLocation);
+ StringRef filename = getFileNameOfSpellingLoc(spellingLocation);
if (loplugin::isSamePathname(filename, SRCDIR "/include/rtl/ref.hxx")) {
return;
}
@@ -360,7 +360,7 @@ bool VCLWidgets::VisitVarDecl(const VarDecl * pVarDecl) {
if (pVarDecl->getInit()) {
checkAssignmentForVclPtrToRawConversion(spellingLocation, pVarDecl->getType().getTypePtr(), pVarDecl->getInit());
}
- StringRef aFileName = compiler.getSourceManager().getFilename(spellingLocation);
+ StringRef aFileName = getFileNameOfSpellingLoc(spellingLocation);
if (loplugin::isSamePathname(aFileName, SRCDIR "/include/vcl/vclptr.hxx"))
return true;
if (loplugin::isSamePathname(aFileName, SRCDIR "/vcl/source/window/layout.cxx"))
@@ -412,7 +412,8 @@ bool VCLWidgets::VisitFieldDecl(const FieldDecl * fieldDecl) {
if (ignoreLocation(fieldDecl)) {
return true;
}
- StringRef aFileName = compiler.getSourceManager().getFilename(compiler.getSourceManager().getSpellingLoc(fieldDecl->getLocStart()));
+ StringRef aFileName = getFileNameOfSpellingLoc(
+ compiler.getSourceManager().getSpellingLoc(fieldDecl->getLocStart()));
if (loplugin::isSamePathname(aFileName, SRCDIR "/include/vcl/vclptr.hxx"))
return true;
if (loplugin::isSamePathname(aFileName, SRCDIR "/include/rtl/ref.hxx"))
@@ -669,7 +670,7 @@ bool VCLWidgets::VisitCXXDeleteExpr(const CXXDeleteExpr *pCXXDeleteExpr)
if (pPointee && isDerivedFromVclReferenceBase(pPointee)) {
SourceLocation spellingLocation = compiler.getSourceManager().getSpellingLoc(
pCXXDeleteExpr->getLocStart());
- StringRef filename = compiler.getSourceManager().getFilename(spellingLocation);
+ StringRef filename = getFileNameOfSpellingLoc(spellingLocation);
if ( !(loplugin::isSamePathname(filename, SRCDIR "/include/vcl/vclreferencebase.hxx")))
{
report(
@@ -845,7 +846,8 @@ bool VCLWidgets::VisitCXXConstructExpr( const CXXConstructExpr* constructExpr )
const CXXConstructorDecl* pConstructorDecl = constructExpr->getConstructor();
const CXXRecordDecl* recordDecl = pConstructorDecl->getParent();
if (isDerivedFromVclReferenceBase(recordDecl)) {
- StringRef aFileName = compiler.getSourceManager().getFilename(compiler.getSourceManager().getSpellingLoc(constructExpr->getLocStart()));
+ StringRef aFileName = getFileNameOfSpellingLoc(
+ compiler.getSourceManager().getSpellingLoc(constructExpr->getLocStart()));
if (!loplugin::isSamePathname(aFileName, SRCDIR "/include/vcl/vclptr.hxx")) {
report(
DiagnosticsEngine::Warning,
commit 243f7d73a0b6ef9cea63bfcca0a07aa9c19e259c
Author: Dennis Francis <dennis.francis at collabora.co.uk>
Date: Fri Jul 6 15:26:39 2018 +0530
Unit tests for a couple of cases...
for the fixes in
commit 49324c8bc90002b89990bcfe17da77ae1de55cd9
"Generalize FG cycle detection for cycles involving
a mix of formula-groups and plain formula-cells
which are not grouped"
Change-Id: I63b4f3ff488f8e788f42527f939769887877b989
Reviewed-on: https://gerrit.libreoffice.org/57047
Tested-by: Jenkins
Reviewed-by: Michael Meeks <michael.meeks at collabora.com>
diff --git a/sc/qa/unit/parallelism.cxx b/sc/qa/unit/parallelism.cxx
index c5c196154123..b9ccf7b9cb3c 100644
--- a/sc/qa/unit/parallelism.cxx
+++ b/sc/qa/unit/parallelism.cxx
@@ -52,6 +52,8 @@ public:
void testVLOOKUPSUM();
void testSingleRef();
void testSUMIFImplicitRange();
+ void testFGCycleWithPlainFormulaCell1();
+ void testFGCycleWithPlainFormulaCell2();
CPPUNIT_TEST_SUITE(ScParallelismTest);
CPPUNIT_TEST(testSUMIFS);
@@ -60,6 +62,8 @@ public:
CPPUNIT_TEST(testVLOOKUPSUM);
CPPUNIT_TEST(testSingleRef);
CPPUNIT_TEST(testSUMIFImplicitRange);
+ CPPUNIT_TEST(testFGCycleWithPlainFormulaCell1);
+ CPPUNIT_TEST(testFGCycleWithPlainFormulaCell2);
CPPUNIT_TEST_SUITE_END();
private:
@@ -396,6 +400,94 @@ void ScParallelismTest::testSUMIFImplicitRange()
m_pDoc->DeleteTab(0);
}
+void ScParallelismTest::testFGCycleWithPlainFormulaCell1()
+{
+ sc::AutoCalcSwitch aACSwitch(*m_pDoc, false);
+ m_pDoc->InsertTab(0, "1");
+ const size_t nNumRows = 1048;
+ // Column A contains no formula-group
+ // A1 = 100
+ m_pDoc->SetValue(0, 0, 0, 100.0);
+ // A500 = B499 + 1
+ m_pDoc->SetFormula(ScAddress(0, 499, 0),
+ "=$B499 + 1",
+ formula::FormulaGrammar::GRAM_NATIVE_UI);
+ // Column B has a formula-group referencing column A.
+ OUString aFormula;
+ for (size_t i = 0; i < nNumRows; ++i)
+ {
+ aFormula = "=$A" + OUString::number(i+1) + " + 100";
+ m_pDoc->SetFormula(ScAddress(1, i, 0),
+ aFormula,
+ formula::FormulaGrammar::GRAM_NATIVE_UI);
+ }
+ m_xDocShell->DoHardRecalc();
+ // Value at A500 must be 101
+ const size_t nVal = 100;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Value at A500", nVal + 1, static_cast<size_t>(m_pDoc->GetValue(0, 499, 0)));
+ for (size_t i = 0; i < nNumRows; ++i)
+ {
+ OString aMsg = "Value at cell B" + OString::number(i+1);
+ size_t nExpected = nVal;
+ if (i == 0)
+ nExpected = 200;
+ else if (i == 499)
+ nExpected = 201;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsg.getStr(), nExpected, static_cast<size_t>(m_pDoc->GetValue(1, i, 0)));
+ }
+ m_pDoc->DeleteTab(0);
+}
+
+void ScParallelismTest::testFGCycleWithPlainFormulaCell2()
+{
+ sc::AutoCalcSwitch aACSwitch(*m_pDoc, false);
+ m_pDoc->InsertTab(0, "1");
+ const size_t nNumRows = 1048;
+ // Column A
+ OUString aFormula;
+ for (size_t i = 0; i < nNumRows; ++i)
+ {
+ aFormula = "=$B" + OUString::number(i+1) + " + 1";
+ m_pDoc->SetFormula(ScAddress(0, i, 0),
+ aFormula,
+ formula::FormulaGrammar::GRAM_NATIVE_UI);
+ }
+ // Column B
+ for (size_t i = 0; i < nNumRows; ++i)
+ {
+ aFormula = "=$C" + OUString::number(i+1) + " + 1";
+ m_pDoc->SetFormula(ScAddress(1, i, 0),
+ aFormula,
+ formula::FormulaGrammar::GRAM_NATIVE_UI);
+ }
+
+ // Column C has no FG but a cell at C500 that references A499
+ m_pDoc->SetFormula(ScAddress(2, 499, 0), // C500
+ "=$A499 + 1",
+ formula::FormulaGrammar::GRAM_NATIVE_UI);
+ m_xDocShell->DoHardRecalc();
+
+ size_t nExpected = 0;
+ for (size_t i = 0; i < nNumRows; ++i)
+ {
+ OString aMsg = "Value at cell A" + OString::number(i+1);
+ nExpected = 2;
+ if (i == 499) // A500 must have value = 5
+ nExpected = 5;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsg.getStr(), nExpected, static_cast<size_t>(m_pDoc->GetValue(0, i, 0)));
+ aMsg = "Value at cell B" + OString::number(i+1);
+ nExpected = 1;
+ if (i == 499) // B500 must have value = 4
+ nExpected = 4;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsg.getStr(), nExpected, static_cast<size_t>(m_pDoc->GetValue(1, i, 0)));
+ }
+
+ // C500 must have value = 3
+ nExpected = 3;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Value at cell C500", nExpected, static_cast<size_t>(m_pDoc->GetValue(2, 499, 0)));
+ m_pDoc->DeleteTab(0);
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(ScParallelismTest);
CPPUNIT_PLUGIN_IMPLEMENT();
commit 24afa5ddbecf54b545b6ff966af1521b8c1b8984
Author: Dennis Francis <dennis.francis at collabora.co.uk>
Date: Fri Jul 6 04:37:01 2018 +0530
Generalize FG cycle detection for...
...cycles involving a mix of formula-groups and plain
formula-cells which are not grouped.
This fixes a crash in tdf#104213/1
Change-Id: I63b8b7379e4e5eaf322a3318f061a9e5fbc931ef
Reviewed-on: https://gerrit.libreoffice.org/57031
Tested-by: Jenkins
Reviewed-by: Michael Meeks <michael.meeks at collabora.com>
diff --git a/sc/inc/formulacell.hxx b/sc/inc/formulacell.hxx
index a9df1a3be625..34c578076d97 100644
--- a/sc/inc/formulacell.hxx
+++ b/sc/inc/formulacell.hxx
@@ -67,7 +67,6 @@ public:
SvNumFormatType mnFormatType;
bool mbInvariant:1;
bool mbSubTotal:1;
- bool mbSeenInPath:1; // For detecting cycle of formula groups
bool mbPartOfCycle:1; // To flag FG's part of a cycle
sal_uInt8 meCalcState;
@@ -134,6 +133,7 @@ private:
number formats as hard number format */
bool mbPostponedDirty : 1; // if cell needs to be set dirty later
bool mbIsExtRef : 1; // has references in ScExternalRefManager; never cleared after set
+ bool mbSeenInPath : 1; // For detecting cycle involving formula groups and singleton formulacells
/**
* Update reference in response to cell copy-n-paste.
@@ -453,6 +453,8 @@ public:
bool IsPostponedDirty() const { return mbPostponedDirty;}
void SetIsExtRef() { mbIsExtRef = true; }
+ bool GetSeenInPath() { return mbSeenInPath; }
+ void SetSeenInPath(bool bSet) { mbSeenInPath = bSet; }
#if DUMP_COLUMN_STORAGE
void Dump() const;
diff --git a/sc/inc/recursionhelper.hxx b/sc/inc/recursionhelper.hxx
index 030e52c04b7c..b2d21daa378b 100644
--- a/sc/inc/recursionhelper.hxx
+++ b/sc/inc/recursionhelper.hxx
@@ -46,7 +46,7 @@ typedef ::std::list< ScFormulaRecursionEntry > ScFormulaRecursionList;
class ScRecursionHelper
{
typedef ::std::stack< ScFormulaCell* > ScRecursionInIterationStack;
- typedef ::std::vector< ScFormulaCellGroup* > ScFGList;
+ typedef ::std::vector< ScFormulaCell* > ScFGList;
ScFormulaRecursionList aRecursionFormulas;
ScFormulaRecursionList::iterator aInsertPos;
ScFormulaRecursionList::iterator aLastIterationStart;
@@ -54,6 +54,8 @@ class ScRecursionHelper
ScFGList aFGList;
sal_uInt16 nRecursionCount;
sal_uInt16 nIteration;
+ // Count of ScFormulaCell::CheckComputeDependencies in current call-stack.
+ sal_uInt16 nDependencyComputationLevel;
bool bInRecursionReturn;
bool bDoingRecursion;
bool bInIterationReturn;
@@ -68,6 +70,9 @@ public:
sal_uInt16 GetRecursionCount() const { return nRecursionCount; }
void IncRecursionCount() { ++nRecursionCount; }
void DecRecursionCount() { --nRecursionCount; }
+ sal_uInt16 GetDepComputeLevel() { return nDependencyComputationLevel; }
+ void IncDepComputeLevel() { ++nDependencyComputationLevel; }
+ void DecDepComputeLevel() { --nDependencyComputationLevel; }
/// A pure recursion return, no iteration.
bool IsInRecursionReturn() const { return bInRecursionReturn &&
!bInIterationReturn; }
@@ -99,9 +104,10 @@ public:
void Clear();
- /** Detects whether the formula-group is part of a simple cycle of formula-groups. */
- bool PushFormulaGroup(ScFormulaCellGroup* pGrp);
+ /** Detects a simple cycle involving formula-groups and singleton formula-cells. */
+ bool PushFormulaGroup(ScFormulaCell* pCell);
void PopFormulaGroup();
+ bool AnyParentFGInCycle();
};
/** A class to wrap ScRecursionHelper::PushFormulaGroup(),
@@ -113,8 +119,18 @@ class ScFormulaGroupCycleCheckGuard
bool mbShouldPop;
public:
ScFormulaGroupCycleCheckGuard() = delete;
- ScFormulaGroupCycleCheckGuard(ScRecursionHelper& rRecursionHelper, ScFormulaCellGroup* pGrp);
+ ScFormulaGroupCycleCheckGuard(ScRecursionHelper& rRecursionHelper, ScFormulaCell* pCell);
~ScFormulaGroupCycleCheckGuard();
+
+};
+
+class ScFormulaGroupDependencyComputeGuard
+{
+ ScRecursionHelper& mrRecHelper;
+public:
+ ScFormulaGroupDependencyComputeGuard() = delete;
+ ScFormulaGroupDependencyComputeGuard(ScRecursionHelper& rRecursionHelper);
+ ~ScFormulaGroupDependencyComputeGuard();
};
#endif // INCLUDED_SC_INC_RECURSIONHELPER_HXX
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 5ef16b9bf2c6..21f38f54711d 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -2855,16 +2855,32 @@ bool ScColumn::HandleRefArrayForParallelism( SCROW nRow1, SCROW nRow2, const ScF
size_t nEnd = std::min(it->size, nOffset+nRowsToRead); // last row + 1
sc::formula_block::const_iterator itCell = sc::formula_block::begin(*it->data);
std::advance(itCell, nOffset);
+ // Loop inside the formula block.
for (size_t i = nOffset; i < nEnd; ++itCell, ++i)
{
- // Loop inside the formula block.
+ // Check if itCell is already in path.
+ // If yes use a cycle guard to mark all elements of the cycle
+ // and return false
+ const ScFormulaCellGroupRef& mxGroupChild = (*itCell)->GetCellGroup();
+ ScFormulaCell* pChildTopCell = mxGroupChild ? mxGroupChild->mpTopCell : *itCell;
+ if (pChildTopCell->GetSeenInPath())
+ {
+ ScRecursionHelper& rRecursionHelper = GetDoc()->GetRecursionHelper();
+ ScFormulaGroupCycleCheckGuard aCycleCheckGuard(rRecursionHelper, pChildTopCell);
+ return false;
+ }
+
(*itCell)->MaybeInterpret();
// child cell's Interpret could result in calling dependency calc
// and that could detect a cycle involving mxGroup
// and do early exit in that case.
if (mxGroup->mbPartOfCycle)
+ {
+ // Set itCell as dirty as itCell may be interpreted in InterpretTail()
+ (*itCell)->SetDirtyVar();
return false;
+ }
}
nRow += nEnd - nOffset;
break;
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index 5c79b1780adb..e370deaacb6c 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -526,7 +526,6 @@ ScFormulaCellGroup::ScFormulaCellGroup() :
mnFormatType(SvNumFormatType::NUMBER),
mbInvariant(false),
mbSubTotal(false),
- mbSeenInPath(false),
mbPartOfCycle(false),
meCalcState(sc::GroupCalcEnabled)
{
@@ -628,6 +627,7 @@ ScFormulaCell::ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos ) :
mbAllowNumberFormatChange(false),
mbPostponedDirty(false),
mbIsExtRef(false),
+ mbSeenInPath(false),
aPos(rPos)
{
}
@@ -659,6 +659,7 @@ ScFormulaCell::ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos,
mbAllowNumberFormatChange(false),
mbPostponedDirty(false),
mbIsExtRef(false),
+ mbSeenInPath(false),
aPos(rPos)
{
Compile( rFormula, true, eGrammar ); // bNoListening, Insert does that
@@ -693,6 +694,7 @@ ScFormulaCell::ScFormulaCell(
mbAllowNumberFormatChange(false),
mbPostponedDirty(false),
mbIsExtRef(false),
+ mbSeenInPath(false),
aPos(rPos)
{
assert(pArray); // Never pass a NULL pointer here.
@@ -742,6 +744,7 @@ ScFormulaCell::ScFormulaCell(
mbAllowNumberFormatChange(false),
mbPostponedDirty(false),
mbIsExtRef(false),
+ mbSeenInPath(false),
aPos(rPos)
{
// RPN array generation
@@ -790,6 +793,7 @@ ScFormulaCell::ScFormulaCell(
mbAllowNumberFormatChange(false),
mbPostponedDirty(false),
mbIsExtRef(false),
+ mbSeenInPath(false),
aPos(rPos)
{
if (bSubTotal)
@@ -821,6 +825,7 @@ ScFormulaCell::ScFormulaCell(const ScFormulaCell& rCell, ScDocument& rDoc, const
mbAllowNumberFormatChange(false),
mbPostponedDirty(false),
mbIsExtRef(false),
+ mbSeenInPath(false),
aPos(rPos)
{
pCode = rCell.pCode->Clone();
@@ -1474,12 +1479,11 @@ void ScFormulaCell::Interpret()
{
ScRecursionHelper& rRecursionHelper = pDocument->GetRecursionHelper();
- if (mxGroup && mxGroup->mbSeenInPath)
+ ScFormulaCell* pTopCell = mxGroup ? mxGroup->mpTopCell : this;
+
+ if (pTopCell->mbSeenInPath && rRecursionHelper.GetDepComputeLevel())
{
- // This call arose from a dependency calculation and
- // we just found a cycle.
- // This will mark all elements in the cycle as parts-of-cycle
- ScFormulaGroupCycleCheckGuard aCycleCheckGuard(rRecursionHelper, mxGroup.get());
+ ScFormulaGroupCycleCheckGuard aCycleCheckGuard(rRecursionHelper, pTopCell);
return;
}
@@ -1541,15 +1545,25 @@ void ScFormulaCell::Interpret()
#if DEBUG_CALCULATION
aDC.enterGroup();
#endif
-
+ bool bPartOfCycleBefore = mxGroup && mxGroup->mbPartOfCycle;
bool bGroupInterpreted = InterpretFormulaGroup();
+ bool bPartOfCycleAfter = mxGroup && mxGroup->mbPartOfCycle;
#if DEBUG_CALCULATION
aDC.leaveGroup();
#endif
if (!bGroupInterpreted)
{
- ScFormulaGroupCycleCheckGuard aCycleCheckGuard(rRecursionHelper, mxGroup.get());
+ // Dependency calc inside InterpretFormulaGroup() failed due to
+ // detection of a cycle and there are parent FG's in the cycle.
+ // Skip InterpretTail() in such cases, only run InterpretTail for the "cycle-starting" FG
+ if (!bPartOfCycleBefore && bPartOfCycleAfter && rRecursionHelper.AnyParentFGInCycle())
+ {
+ pDocument->DecInterpretLevel();
+ return;
+ }
+
+ ScFormulaGroupCycleCheckGuard aCycleCheckGuard(rRecursionHelper, this);
InterpretTail( pDocument->GetNonThreadedContext(), SCITP_NORMAL);
}
@@ -4331,6 +4345,7 @@ struct ScDependantsCalculator
// Partially from ScGroupTokenConverter::convert in sc/source/core/data/grouptokenconverter.cxx
ScRangeList aRangeList;
+ bool bHasSelfReferences = false;
for (auto p: mrCode.RPNTokens())
{
switch (p->GetType())
@@ -4346,7 +4361,10 @@ struct ScDependantsCalculator
if (aRef.IsRowRel())
{
if (isSelfReferenceRelative(aRefPos, aRef.Row()))
- return false;
+ {
+ bHasSelfReferences = true;
+ continue;
+ }
// Trim data array length to actual data range.
SCROW nTrimLen = trimLength(aRefPos.Tab(), aRefPos.Col(), aRefPos.Col(), aRefPos.Row(), mnLen);
@@ -4357,7 +4375,10 @@ struct ScDependantsCalculator
else
{
if (isSelfReferenceAbsolute(aRefPos))
- return false;
+ {
+ bHasSelfReferences = true;
+ continue;
+ }
aRangeList.Join(ScRange(aRefPos.Col(), aRefPos.Row(), aRefPos.Tab()));
}
@@ -4377,22 +4398,37 @@ struct ScDependantsCalculator
if (bIsRef1RowRel)
{
if (isSelfReferenceRelative(aAbs.aStart, aRef.Ref1.Row()))
- return false;
+ {
+ bHasSelfReferences = true;
+ continue;
+ }
}
else if (isSelfReferenceAbsolute(aAbs.aStart))
- return false;
+ {
+ bHasSelfReferences = true;
+ continue;
+ }
bool bIsRef2RowRel = aRef.Ref2.IsRowRel();
if (bIsRef2RowRel)
{
if (isSelfReferenceRelative(aAbs.aEnd, aRef.Ref2.Row()))
- return false;
+ {
+ bHasSelfReferences = true;
+ continue;
+ }
}
else if (isSelfReferenceAbsolute(aAbs.aEnd))
- return false;
+ {
+ bHasSelfReferences = true;
+ continue;
+ }
if (isDoubleRefSpanGroupRange(aAbs, bIsRef1RowRel, bIsRef2RowRel))
- return false;
+ {
+ bHasSelfReferences = true;
+ continue;
+ }
// Row reference is relative.
bool bAbsLast = !aRef.Ref2.IsRowRel();
@@ -4421,6 +4457,9 @@ struct ScDependantsCalculator
}
}
+ // Compute dependencies irrespective of the presence of any self references.
+ // These dependencies would get computed via InterpretTail anyway when we disable group calc, so lets do it now.
+ // The advantage is that the FG's get marked for cycles early if present, and can avoid lots of complications.
for (size_t i = 0; i < aRangeList.size(); ++i)
{
const ScRange & rRange = aRangeList[i];
@@ -4432,7 +4471,7 @@ struct ScDependantsCalculator
return false;
}
}
- return true;
+ return !bHasSelfReferences;
}
};
@@ -4503,7 +4542,7 @@ bool ScFormulaCell::CheckComputeDependencies(sc::FormulaLogger::GroupScope& rSco
bool bOKToParallelize = false;
{
- ScFormulaGroupCycleCheckGuard aCycleCheckGuard(rRecursionHelper, mxGroup.get());
+ ScFormulaGroupCycleCheckGuard aCycleCheckGuard(rRecursionHelper, this);
if (mxGroup->mbPartOfCycle)
{
mxGroup->meCalcState = sc::GroupCalcDisabled;
@@ -4511,6 +4550,7 @@ bool ScFormulaCell::CheckComputeDependencies(sc::FormulaLogger::GroupScope& rSco
return false;
}
+ ScFormulaGroupDependencyComputeGuard aDepComputeGuard(rRecursionHelper);
ScDependantsCalculator aCalculator(*pDocument, *pCode, *this, mxGroup->mpTopCell->aPos);
bOKToParallelize = aCalculator.DoIt();
}
diff --git a/sc/source/core/tool/recursionhelper.cxx b/sc/source/core/tool/recursionhelper.cxx
index 8cfef9776e35..dd5be99c7155 100644
--- a/sc/source/core/tool/recursionhelper.cxx
+++ b/sc/source/core/tool/recursionhelper.cxx
@@ -13,6 +13,7 @@
void ScRecursionHelper::Init()
{
nRecursionCount = 0;
+ nDependencyComputationLevel = 0;
bInRecursionReturn = bDoingRecursion = bInIterationReturn = false;
aInsertPos = GetIterationEnd();
ResetIteration();
@@ -96,12 +97,22 @@ void ScRecursionHelper::Clear()
Init();
}
-bool ScRecursionHelper::PushFormulaGroup(ScFormulaCellGroup* pGrp)
+static ScFormulaCell* lcl_GetTopCell(ScFormulaCell* pCell)
{
- if (!pGrp)
- return false;
+ if (!pCell)
+ return nullptr;
+
+ const ScFormulaCellGroupRef& mxGroup = pCell->GetCellGroup();
+ if (!mxGroup)
+ return pCell;
+ return mxGroup->mpTopCell;
+}
+
+bool ScRecursionHelper::PushFormulaGroup(ScFormulaCell* pCell)
+{
+ assert(pCell);
- if (pGrp->mbSeenInPath)
+ if (pCell->GetSeenInPath())
{
// Found a simple cycle of formula-groups.
// Disable group calc for all elements of this cycle.
@@ -111,14 +122,16 @@ bool ScRecursionHelper::PushFormulaGroup(ScFormulaCellGroup* pGrp)
{
--nIdx;
assert(nIdx >= 0);
- aFGList[nIdx]->mbPartOfCycle = true;
- } while (aFGList[nIdx] != pGrp);
+ const ScFormulaCellGroupRef& mxGroup = aFGList[nIdx]->GetCellGroup();
+ if (mxGroup)
+ mxGroup->mbPartOfCycle = true;
+ } while (aFGList[nIdx] != pCell);
return false;
}
- pGrp->mbSeenInPath = true;
- aFGList.push_back(pGrp);
+ pCell->SetSeenInPath(true);
+ aFGList.push_back(pCell);
return true;
}
@@ -126,15 +139,34 @@ void ScRecursionHelper::PopFormulaGroup()
{
if (aFGList.empty())
return;
- ScFormulaCellGroup* pGrp = aFGList.back();
- pGrp->mbSeenInPath = false;
+ ScFormulaCell* pCell = aFGList.back();
+ pCell->SetSeenInPath(false);
aFGList.pop_back();
}
-ScFormulaGroupCycleCheckGuard::ScFormulaGroupCycleCheckGuard(ScRecursionHelper& rRecursionHelper, ScFormulaCellGroup* pGrp) :
+bool ScRecursionHelper::AnyParentFGInCycle()
+{
+ sal_Int32 nIdx = aFGList.size() - 1;
+ while (nIdx >= 0)
+ {
+ const ScFormulaCellGroupRef& mxGroup = aFGList[nIdx]->GetCellGroup();
+ if (mxGroup)
+ return mxGroup->mbPartOfCycle;
+ --nIdx;
+ };
+ return false;
+}
+
+ScFormulaGroupCycleCheckGuard::ScFormulaGroupCycleCheckGuard(ScRecursionHelper& rRecursionHelper, ScFormulaCell* pCell) :
mrRecHelper(rRecursionHelper)
{
- mbShouldPop = mrRecHelper.PushFormulaGroup(pGrp);
+ if (pCell)
+ {
+ pCell = lcl_GetTopCell(pCell);
+ mbShouldPop = mrRecHelper.PushFormulaGroup(pCell);
+ }
+ else
+ mbShouldPop = false;
}
ScFormulaGroupCycleCheckGuard::~ScFormulaGroupCycleCheckGuard()
@@ -143,4 +175,15 @@ ScFormulaGroupCycleCheckGuard::~ScFormulaGroupCycleCheckGuard()
mrRecHelper.PopFormulaGroup();
}
+ScFormulaGroupDependencyComputeGuard::ScFormulaGroupDependencyComputeGuard(ScRecursionHelper& rRecursionHelper) :
+ mrRecHelper(rRecursionHelper)
+{
+ mrRecHelper.IncDepComputeLevel();
+}
+
+ScFormulaGroupDependencyComputeGuard::~ScFormulaGroupDependencyComputeGuard()
+{
+ mrRecHelper.DecDepComputeLevel();
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 0f95580d392bb1a6f103f3a1543fb61a16f9f263
Author: Dennis Francis <dennis.francis at collabora.co.uk>
Date: Thu Jul 5 16:30:37 2018 +0530
Use cycle guard for calls to InterpretTail too
Some formula-groups even though a part of a cycle
may get skipped from getting flagged(mbPartOfCycle)
in the dependency calculator because it has other
problems like self references. Such FG's can be
caught when they through InterpretTail() by having
a cycle guard there.
Concretely it fixes a crash in the bugdoc of
tdf#94271-2.
Change-Id: I508df88804c7cd8dbbb6497188b1c9559bec3aa6
Reviewed-on: https://gerrit.libreoffice.org/57004
Tested-by: Jenkins
Reviewed-by: Michael Meeks <michael.meeks at collabora.com>
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index 96aabc5ae07c..5c79b1780adb 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -1540,14 +1540,18 @@ void ScFormulaCell::Interpret()
#if DEBUG_CALCULATION
aDC.enterGroup();
+#endif
+
bool bGroupInterpreted = InterpretFormulaGroup();
+
+#if DEBUG_CALCULATION
aDC.leaveGroup();
+#endif
if (!bGroupInterpreted)
+ {
+ ScFormulaGroupCycleCheckGuard aCycleCheckGuard(rRecursionHelper, mxGroup.get());
InterpretTail( pDocument->GetNonThreadedContext(), SCITP_NORMAL);
-#else
- if (!InterpretFormulaGroup())
- InterpretTail( pDocument->GetNonThreadedContext(), SCITP_NORMAL);
-#endif
+ }
pDocument->DecInterpretLevel();
}
diff --git a/sc/source/core/tool/recursionhelper.cxx b/sc/source/core/tool/recursionhelper.cxx
index 0c185dba3c6b..8cfef9776e35 100644
--- a/sc/source/core/tool/recursionhelper.cxx
+++ b/sc/source/core/tool/recursionhelper.cxx
@@ -98,7 +98,9 @@ void ScRecursionHelper::Clear()
bool ScRecursionHelper::PushFormulaGroup(ScFormulaCellGroup* pGrp)
{
- assert(pGrp);
+ if (!pGrp)
+ return false;
+
if (pGrp->mbSeenInPath)
{
// Found a simple cycle of formula-groups.
commit 9ceeb4619ba762c47589023d99c43c774caab441
Author: Tamas Bunth <tamas.bunth at collabora.co.uk>
Date: Tue Jun 26 13:45:40 2018 +0200
HSQLDB Migration: overwrite backup xml
Change-Id: I080568f2d278e8a7153188497e3987217d9d188f
Reviewed-on: https://gerrit.libreoffice.org/56464
Tested-by: Jenkins
Reviewed-by: Tamás Bunth <btomi96 at gmail.com>
diff --git a/dbaccess/source/core/dataaccess/datasource.cxx b/dbaccess/source/core/dataaccess/datasource.cxx
index 29d5816bc043..597c5a6d560b 100644
--- a/dbaccess/source/core/dataaccess/datasource.cxx
+++ b/dbaccess/source/core/dataaccess/datasource.cxx
@@ -599,8 +599,12 @@ Reference< XConnection > ODatabaseSource::buildLowLevelConnection(const OUString
{
// back up content xml file if migration was successful
Reference<XStorage> xRootStorage = m_pImpl->getOrCreateRootStorage();
+
+ constexpr char BACKUP_XML_NAME[] = "content_before_migration.xml";
+ if(xRootStorage->isStreamElement(BACKUP_XML_NAME))
+ xRootStorage->removeElement(BACKUP_XML_NAME);
xRootStorage->copyElementTo("content.xml", xRootStorage,
- "content_before_migration.xml");
+ BACKUP_XML_NAME);
m_pImpl->m_sConnectURL = "sdbc:embedded:firebird";
}
commit 9eb929aa8cb3f5b0fee1264119a55cdd8cbe8f0e
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date: Fri Jul 6 09:46:01 2018 +0200
connectivity: turn on clang-format for the Writer driver
I (tried to) keep this consistent locally with astyle in the past,
switching to clang-format means consistency is enforced by CI.
Change-Id: I1016e253c6536b207a05328e5f6f13de37889588
Reviewed-on: https://gerrit.libreoffice.org/57046
Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
Tested-by: Jenkins
diff --git a/connectivity/source/drivers/writer/WCatalog.cxx b/connectivity/source/drivers/writer/WCatalog.cxx
index 9d273e201945..0baa759da14c 100644
--- a/connectivity/source/drivers/writer/WCatalog.cxx
+++ b/connectivity/source/drivers/writer/WCatalog.cxx
@@ -34,21 +34,21 @@ namespace connectivity
{
namespace writer
{
-
-OWriterCatalog::OWriterCatalog(OWriterConnection* pConnection) : file::OFileCatalog(pConnection)
+OWriterCatalog::OWriterCatalog(OWriterConnection* pConnection)
+ : file::OFileCatalog(pConnection)
{
}
void OWriterCatalog::refreshTables()
{
- ::std::vector< OUString> aVector;
+ ::std::vector<OUString> aVector;
uno::Sequence<OUString> aTypes;
OWriterConnection::ODocHolder aDocHolder(static_cast<OWriterConnection*>(m_pConnection));
- uno::Reference< sdbc::XResultSet > xResult = m_xMetaData->getTables(uno::Any(), "%", "%", aTypes);
+ uno::Reference<sdbc::XResultSet> xResult = m_xMetaData->getTables(uno::Any(), "%", "%", aTypes);
if (xResult.is())
{
- uno::Reference< sdbc::XRow > xRow(xResult, uno::UNO_QUERY);
+ uno::Reference<sdbc::XRow> xRow(xResult, uno::UNO_QUERY);
while (xResult->next())
aVector.push_back(xRow->getString(3));
}
diff --git a/connectivity/source/drivers/writer/WConnection.cxx b/connectivity/source/drivers/writer/WConnection.cxx
index cede7c409b0e..26234ed5e7cf 100644
--- a/connectivity/source/drivers/writer/WConnection.cxx
+++ b/connectivity/source/drivers/writer/WConnection.cxx
@@ -40,20 +40,22 @@ namespace connectivity
{
namespace writer
{
-
-OWriterConnection::OWriterConnection(ODriver* _pDriver) : OConnection(_pDriver),m_nDocCount(0)
+OWriterConnection::OWriterConnection(ODriver* _pDriver)
+ : OConnection(_pDriver)
+ , m_nDocCount(0)
{
}
OWriterConnection::~OWriterConnection() = default;
-void OWriterConnection::construct(const OUString& rURL, const uno::Sequence< beans::PropertyValue >& rInfo)
+void OWriterConnection::construct(const OUString& rURL,
+ const uno::Sequence<beans::PropertyValue>& rInfo)
{
// open file
sal_Int32 nLen = rURL.indexOf(':');
- nLen = rURL.indexOf(':',nLen+1);
- OUString aDSN(rURL.copy(nLen+1));
+ nLen = rURL.indexOf(':', nLen + 1);
+ OUString aDSN(rURL.copy(nLen + 1));
m_aFileName = aDSN;
INetURLObject aURL;
@@ -73,8 +75,8 @@ void OWriterConnection::construct(const OUString& rURL, const uno::Sequence< bea
m_sPassword.clear();
const char pPwd[] = "password";
- const beans::PropertyValue* pIter = rInfo.getConstArray();
- const beans::PropertyValue* pEnd = pIter + rInfo.getLength();
+ const beans::PropertyValue* pIter = rInfo.getConstArray();
+ const beans::PropertyValue* pEnd = pIter + rInfo.getLength();
for (; pIter != pEnd; ++pIter)
{
if (pIter->Name == pPwd)
@@ -104,18 +106,18 @@ uno::Reference<text::XTextDocument> const& OWriterConnection::acquireDoc()
if (!m_sPassword.isEmpty())
{
const sal_Int32 nPos = aArgs.getLength();
- aArgs.realloc(nPos+1);
+ aArgs.realloc(nPos + 1);
aArgs[nPos].Name = "Password";
aArgs[nPos].Value <<= m_sPassword;
}
- uno::Reference< frame::XDesktop2 > xDesktop = frame::Desktop::create(getDriver()->getComponentContext());
- uno::Reference< lang::XComponent > xComponent;
+ uno::Reference<frame::XDesktop2> xDesktop
+ = frame::Desktop::create(getDriver()->getComponentContext());
+ uno::Reference<lang::XComponent> xComponent;
uno::Any aLoaderException;
try
{
- xComponent = xDesktop->loadComponentFromURL(
- m_aFileName, "_blank", 0, aArgs);
+ xComponent = xDesktop->loadComponentFromURL(m_aFileName, "_blank", 0, aArgs);
}
catch (const uno::Exception&)
{
@@ -133,13 +135,13 @@ uno::Reference<text::XTextDocument> const& OWriterConnection::acquireDoc()
uno::Exception aLoaderError;
OSL_VERIFY(aLoaderException >>= aLoaderError);
- SAL_WARN("connectivity.writer", "empty m_xDoc, exception type: " << aLoaderException.getValueTypeName() << ", error message: " << aLoaderError);
+ SAL_WARN("connectivity.writer",
+ "empty m_xDoc, exception type: " << aLoaderException.getValueTypeName()
+ << ", error message: " << aLoaderError);
}
const OUString sError(m_aResources.getResourceStringWithSubstitution(
- STR_COULD_NOT_LOAD_FILE,
- "$filename$", m_aFileName
- ));
+ STR_COULD_NOT_LOAD_FILE, "$filename$", m_aFileName));
::dbtools::throwGenericSQLException(sError, *this);
}
osl_atomic_increment(&m_nDocCount);
@@ -154,7 +156,7 @@ void OWriterConnection::releaseDoc()
{
if (m_xCloseVetoButTerminateListener.is())
{
- m_xCloseVetoButTerminateListener->stop(); // dispose m_xDoc
+ m_xCloseVetoButTerminateListener->stop(); // dispose m_xDoc
m_xCloseVetoButTerminateListener.clear();
}
m_xDoc.clear();
@@ -168,7 +170,7 @@ void OWriterConnection::disposing()
m_nDocCount = 0;
if (m_xCloseVetoButTerminateListener.is())
{
- m_xCloseVetoButTerminateListener->stop(); // dispose m_xDoc
+ m_xCloseVetoButTerminateListener->stop(); // dispose m_xDoc
m_xCloseVetoButTerminateListener.clear();
}
m_xDoc.clear();
@@ -178,17 +180,15 @@ void OWriterConnection::disposing()
// XServiceInfo
+IMPLEMENT_SERVICE_INFO(OWriterConnection, "com.sun.star.sdbc.drivers.writer.Connection",
+ "com.sun.star.sdbc.Connection")
-IMPLEMENT_SERVICE_INFO(OWriterConnection, "com.sun.star.sdbc.drivers.writer.Connection", "com.sun.star.sdbc.Connection")
-
-
-uno::Reference< sdbc::XDatabaseMetaData > SAL_CALL OWriterConnection::getMetaData()
+uno::Reference<sdbc::XDatabaseMetaData> SAL_CALL OWriterConnection::getMetaData()
{
::osl::MutexGuard aGuard(m_aMutex);
checkDisposed(OConnection_BASE::rBHelper.bDisposed);
-
- uno::Reference< sdbc::XDatabaseMetaData > xMetaData = m_xMetaData;
+ uno::Reference<sdbc::XDatabaseMetaData> xMetaData = m_xMetaData;
... etc. - the rest is truncated
More information about the Libreoffice-commits
mailing list