/************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_svx.hxx" #include #include #include #include "svx/svdstr.hrc" // Namen aus der Resource #include "svx/svdglob.hxx" // StringCache #include #include #include #include //////////////////////////////////////////////////////////////////////////////////////////////////// void SdrGlueEditView::ImpClearVars() { } SdrGlueEditView::SdrGlueEditView(SdrModel* pModel1, OutputDevice* pOut): SdrPolyEditView(pModel1,pOut) { ImpClearVars(); } SdrGlueEditView::~SdrGlueEditView() { } //////////////////////////////////////////////////////////////////////////////////////////////////// void SdrGlueEditView::ImpDoMarkedGluePoints(PGlueDoFunc pDoFunc, BOOL bConst, const void* p1, const void* p2, const void* p3, const void* p4, const void* p5) { ULONG nMarkAnz=GetMarkedObjectCount(); for (ULONG nm=0; nmGetMarkedSdrObj(); const SdrUShortCont* pPts=pM->GetMarkedGluePoints(); ULONG nPtAnz=pPts==NULL ? 0 : pPts->GetCount(); if (nPtAnz!=0) { SdrGluePointList* pGPL=NULL; if (bConst) { const SdrGluePointList* pConstGPL=pObj->GetGluePointList(); pGPL=(SdrGluePointList*)pConstGPL; } else { pGPL=pObj->ForceGluePointList(); } if (pGPL!=NULL) { if(!bConst && IsUndoEnabled() ) AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj)); for (ULONG nPtNum=0; nPtNumGetObject(nPtNum); USHORT nGlueIdx=pGPL->FindGluePoint(nPtId); if (nGlueIdx!=SDRGLUEPOINT_NOTFOUND) { SdrGluePoint& rGP=(*pGPL)[nGlueIdx]; (*pDoFunc)(rGP,pObj,p1,p2,p3,p4,p5); } } if (!bConst) { pObj->SetChanged(); pObj->BroadcastObjectChange(); } } } } if (!bConst && nMarkAnz!=0) pMod->SetChanged(); } //////////////////////////////////////////////////////////////////////////////////////////////////// static void ImpGetEscDir(SdrGluePoint& rGP, const SdrObject* /*pObj*/, const void* pbFirst, const void* pnThisEsc, const void* pnRet, const void*, const void*) { USHORT& nRet=*(USHORT*)pnRet; BOOL& bFirst=*(BOOL*)pbFirst; if (nRet!=FUZZY) { USHORT nEsc=rGP.GetEscDir(); BOOL bOn=(nEsc & *(USHORT*)pnThisEsc)!=0; if (bFirst) { nRet=bOn; bFirst=FALSE; } else if (nRet!=bOn) nRet=FUZZY; } } TRISTATE SdrGlueEditView::IsMarkedGluePointsEscDir(USHORT nThisEsc) const { ForceUndirtyMrkPnt(); BOOL bFirst=TRUE; USHORT nRet=FALSE; ((SdrGlueEditView*)this)->ImpDoMarkedGluePoints(ImpGetEscDir,TRUE,&bFirst,&nThisEsc,&nRet); return (TRISTATE)nRet; } static void ImpSetEscDir(SdrGluePoint& rGP, const SdrObject* /*pObj*/, const void* pnThisEsc, const void* pbOn, const void*, const void*, const void*) { USHORT nEsc=rGP.GetEscDir(); if (*(BOOL*)pbOn) nEsc|=*(USHORT*)pnThisEsc; else nEsc&=~*(USHORT*)pnThisEsc; rGP.SetEscDir(nEsc); } void SdrGlueEditView::SetMarkedGluePointsEscDir(USHORT nThisEsc, BOOL bOn) { ForceUndirtyMrkPnt(); BegUndo(ImpGetResStr(STR_EditSetGlueEscDir),GetDescriptionOfMarkedGluePoints()); ImpDoMarkedGluePoints(ImpSetEscDir,FALSE,&nThisEsc,&bOn); EndUndo(); } //////////////////////////////////////////////////////////////////////////////////////////////////// static void ImpGetPercent(SdrGluePoint& rGP, const SdrObject* /*pObj*/, const void* pbFirst, const void* pnRet, const void*, const void*, const void*) { USHORT& nRet=*(USHORT*)pnRet; BOOL& bFirst=*(BOOL*)pbFirst; if (nRet!=FUZZY) { bool bOn=rGP.IsPercent(); if (bFirst) { nRet=bOn; bFirst=FALSE; } else if ((nRet!=0)!=bOn) nRet=FUZZY; } } TRISTATE SdrGlueEditView::IsMarkedGluePointsPercent() const { ForceUndirtyMrkPnt(); BOOL bFirst=TRUE; USHORT nRet=TRUE; ((SdrGlueEditView*)this)->ImpDoMarkedGluePoints(ImpGetPercent,TRUE,&bFirst,&nRet); return (TRISTATE)nRet; } static void ImpSetPercent(SdrGluePoint& rGP, const SdrObject* pObj, const void* pbOn, const void*, const void*, const void*, const void*) { Point aPos(rGP.GetAbsolutePos(*pObj)); rGP.SetPercent(*(BOOL*)pbOn); rGP.SetAbsolutePos(aPos,*pObj); } void SdrGlueEditView::SetMarkedGluePointsPercent(BOOL bOn) { ForceUndirtyMrkPnt(); BegUndo(ImpGetResStr(STR_EditSetGluePercent),GetDescriptionOfMarkedGluePoints()); ImpDoMarkedGluePoints(ImpSetPercent,FALSE,&bOn); EndUndo(); } //////////////////////////////////////////////////////////////////////////////////////////////////// static void ImpGetAlign(SdrGluePoint& rGP, const SdrObject* /*pObj*/, const void* pbFirst, const void* pbDontCare, const void* pbVert, const void* pnRet, const void*) { USHORT& nRet=*(USHORT*)pnRet; BOOL& bFirst=*(BOOL*)pbFirst; BOOL& bDontCare=*(BOOL*)pbDontCare; BOOL bVert=*(BOOL*)pbVert; if (!bDontCare) { USHORT nAlg=0; if (bVert) { nAlg=rGP.GetVertAlign(); } else { nAlg=rGP.GetHorzAlign(); } if (bFirst) { nRet=nAlg; bFirst=FALSE; } else if (nRet!=nAlg) { if (bVert) { nRet=SDRVERTALIGN_DONTCARE; } else { nRet=SDRHORZALIGN_DONTCARE; } bDontCare=TRUE; } } } USHORT SdrGlueEditView::GetMarkedGluePointsAlign(BOOL bVert) const { ForceUndirtyMrkPnt(); BOOL bFirst=TRUE; BOOL bDontCare=FALSE; USHORT nRet=0; ((SdrGlueEditView*)this)->ImpDoMarkedGluePoints(ImpGetAlign,TRUE,&bFirst,&bDontCare,&bVert,&nRet); return nRet; } static void ImpSetAlign(SdrGluePoint& rGP, const SdrObject* pObj, const void* pbVert, const void* pnAlign, const void*, const void*, const void*) { Point aPos(rGP.GetAbsolutePos(*pObj)); if (*(BOOL*)pbVert) { // bVert? rGP.SetVertAlign(*(USHORT*)pnAlign); } else { rGP.SetHorzAlign(*(USHORT*)pnAlign); } rGP.SetAbsolutePos(aPos,*pObj); } void SdrGlueEditView::SetMarkedGluePointsAlign(BOOL bVert, USHORT nAlign) { ForceUndirtyMrkPnt(); BegUndo(ImpGetResStr(STR_EditSetGlueAlign),GetDescriptionOfMarkedGluePoints()); ImpDoMarkedGluePoints(ImpSetAlign,FALSE,&bVert,&nAlign); EndUndo(); } //////////////////////////////////////////////////////////////////////////////////////////////////// BOOL SdrGlueEditView::IsDeleteMarkedGluePointsPossible() const { return HasMarkedGluePoints(); } void SdrGlueEditView::DeleteMarkedGluePoints() { BrkAction(); ForceUndirtyMrkPnt(); const bool bUndo = IsUndoEnabled(); if( bUndo ) BegUndo(ImpGetResStr(STR_EditDelete),GetDescriptionOfMarkedGluePoints(),SDRREPFUNC_OBJ_DELETE); ULONG nMarkAnz=GetMarkedObjectCount(); for (ULONG nm=0; nmGetMarkedSdrObj(); const SdrUShortCont* pPts=pM->GetMarkedGluePoints(); ULONG nPtAnz=pPts==NULL ? 0 : pPts->GetCount(); if (nPtAnz!=0) { SdrGluePointList* pGPL=pObj->ForceGluePointList(); if (pGPL!=NULL) { if( bUndo ) AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj)); for (ULONG nPtNum=0; nPtNumGetObject(nPtNum); USHORT nGlueIdx=pGPL->FindGluePoint(nPtId); if (nGlueIdx!=SDRGLUEPOINT_NOTFOUND) { pGPL->Delete(nGlueIdx); } } pObj->SetChanged(); pObj->BroadcastObjectChange(); } } } if( bUndo ) EndUndo(); UnmarkAllGluePoints(); if (nMarkAnz!=0) pMod->SetChanged(); } //////////////////////////////////////////////////////////////////////////////////////////////////// void SdrGlueEditView::ImpCopyMarkedGluePoints() { const bool bUndo = IsUndoEnabled(); if( bUndo ) BegUndo(); ULONG nMarkAnz=GetMarkedObjectCount(); for (ULONG nm=0; nmGetMarkedSdrObj(); SdrUShortCont* pPts=pM->GetMarkedGluePoints(); SdrGluePointList* pGPL=pObj->ForceGluePointList(); ULONG nPtAnz=pPts==NULL ? 0 : pPts->GetCount(); if (nPtAnz!=0 && pGPL!=NULL) { if( bUndo ) AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj)); for (ULONG nPtNum=0; nPtNumGetObject(nPtNum); USHORT nGlueIdx=pGPL->FindGluePoint(nPtId); if (nGlueIdx!=SDRGLUEPOINT_NOTFOUND) { SdrGluePoint aNewGP((*pGPL)[nGlueIdx]); // GluePoint klonen USHORT nNewIdx=pGPL->Insert(aNewGP); // und einfuegen USHORT nNewId=(*pGPL)[nNewIdx].GetId(); // Id des neuen GluePoints ermitteln pPts->Replace(nNewId,nPtNum); // und diesen markieren (anstelle des alten) } } } } if( bUndo ) EndUndo(); if (nMarkAnz!=0) pMod->SetChanged(); } //////////////////////////////////////////////////////////////////////////////////////////////////// void SdrGlueEditView::ImpTransformMarkedGluePoints(PGlueTrFunc pTrFunc, const void* p1, const void* p2, const void* p3, const void* p4, const void* p5) { ULONG nMarkAnz=GetMarkedObjectCount(); for (ULONG nm=0; nmGetMarkedSdrObj(); const SdrUShortCont* pPts=pM->GetMarkedGluePoints(); ULONG nPtAnz=pPts==NULL ? 0 : pPts->GetCount(); if (nPtAnz!=0) { SdrGluePointList* pGPL=pObj->ForceGluePointList(); if (pGPL!=NULL) { if( IsUndoEnabled() ) AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj)); for (ULONG nPtNum=0; nPtNumGetObject(nPtNum); USHORT nGlueIdx=pGPL->FindGluePoint(nPtId); if (nGlueIdx!=SDRGLUEPOINT_NOTFOUND) { SdrGluePoint& rGP=(*pGPL)[nGlueIdx]; Point aPos(rGP.GetAbsolutePos(*pObj)); (*pTrFunc)(aPos,p1,p2,p3,p4,p5); rGP.SetAbsolutePos(aPos,*pObj); } } pObj->SetChanged(); pObj->BroadcastObjectChange(); } } } if (nMarkAnz!=0) pMod->SetChanged(); } //////////////////////////////////////////////////////////////////////////////////////////////////// static void ImpMove(Point& rPt, const void* p1, const void* /*p2*/, const void* /*p3*/, const void* /*p4*/, const void* /*p5*/) { rPt.X()+=((const Size*)p1)->Width(); rPt.Y()+=((const Size*)p1)->Height(); } void SdrGlueEditView::MoveMarkedGluePoints(const Size& rSiz, bool bCopy) { ForceUndirtyMrkPnt(); XubString aStr(ImpGetResStr(STR_EditMove)); if (bCopy) aStr+=ImpGetResStr(STR_EditWithCopy); BegUndo(aStr,GetDescriptionOfMarkedGluePoints(),SDRREPFUNC_OBJ_MOVE); if (bCopy) ImpCopyMarkedGluePoints(); ImpTransformMarkedGluePoints(ImpMove,&rSiz); EndUndo(); AdjustMarkHdl(); } //////////////////////////////////////////////////////////////////////////////////////////////////// static void ImpResize(Point& rPt, const void* p1, const void* p2, const void* p3, const void* /*p4*/, const void* /*p5*/) { ResizePoint(rPt,*(const Point*)p1,*(const Fraction*)p2,*(const Fraction*)p3); } void SdrGlueEditView::ResizeMarkedGluePoints(const Point& rRef, const Fraction& xFact, const Fraction& yFact, bool bCopy) { ForceUndirtyMrkPnt(); XubString aStr(ImpGetResStr(STR_EditResize)); if (bCopy) aStr+=ImpGetResStr(STR_EditWithCopy); BegUndo(aStr,GetDescriptionOfMarkedGluePoints(),SDRREPFUNC_OBJ_RESIZE); if (bCopy) ImpCopyMarkedGluePoints(); ImpTransformMarkedGluePoints(ImpResize,&rRef,&xFact,&yFact); EndUndo(); AdjustMarkHdl(); } //////////////////////////////////////////////////////////////////////////////////////////////////// static void ImpRotate(Point& rPt, const void* p1, const void* /*p2*/, const void* p3, const void* p4, const void* /*p5*/) { RotatePoint(rPt,*(const Point*)p1,*(const double*)p3,*(const double*)p4); } void SdrGlueEditView::RotateMarkedGluePoints(const Point& rRef, long nWink, bool bCopy) { ForceUndirtyMrkPnt(); XubString aStr(ImpGetResStr(STR_EditRotate)); if (bCopy) aStr+=ImpGetResStr(STR_EditWithCopy); BegUndo(aStr,GetDescriptionOfMarkedGluePoints(),SDRREPFUNC_OBJ_ROTATE); if (bCopy) ImpCopyMarkedGluePoints(); double nSin=sin(nWink*nPi180); double nCos=cos(nWink*nPi180); ImpTransformMarkedGluePoints(ImpRotate,&rRef,&nWink,&nSin,&nCos); EndUndo(); AdjustMarkHdl(); } LibreOffice 核心代码仓库文档基金会
summaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
authorAshod Nakashian <ashodnakashian@yahoo.com>2015-11-14 18:48:49 -0500
committerCaolán McNamara <caolanm@redhat.com>2015-11-15 20:31:35 +0000
commit06116bd15b1fb8b03e65e1166f5ddad929614246 (patch)
treeb2849066315c89f1bcd1d1c9bc903b82e7c00523 /bin
parent6474336e36447b1797bdf429a5f2ad5016a34262 (diff)
Fast PCH generator and optimized PCH files
Ported update_pch.sh to Python with improved performance and features. The new script is invoked from the same update_pch.sh which calls it for each library in parallel, although it can be invoked directly. The ported script (update_pch) updates all PCH files in ~15 seconds where the old script took ~4500 seconds. In addition, the new script supports 3-tiered headers (system, module, and local) and is very flexible to support other improvement. It has a per-library optimal configuration settings that can be updated using another new scripts (update_pch_autotune.sh) which finds optimal per-PCH settings. PCH files have been generated using the new scripts which builds significantly faster (2-3x, depending on module and configuration) and the intermediate binaries are noticably smaller (by several GBs). The new script stamps each generated PCH file with the command that generated it to make it trivial for users to update them, and also adds the command to invoke another script (update_pch_bisect) that helps find missing headers or conflicting headers that may break the build after updating the PCH. Finally update_pch has built-in unit-tests for makefile parsing and other core functionality. Change-Id: Ib933b50e50374d7e2e7e3e95ba8799b0cc8a27fa Reviewed-on: https://gerrit.libreoffice.org/19965 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'bin')
-rwxr-xr-xbin/update_pch1177
-rwxr-xr-xbin/update_pch.sh170
-rwxr-xr-xbin/update_pch_autotune.sh210
-rw-r--r--bin/update_pch_bisect9
4 files changed, 1406 insertions, 160 deletions
diff --git a/bin/update_pch b/bin/update_pch
new file mode 100755
index 000000000000..fa2294d4cd57
--- /dev/null
+++ b/bin/update_pch
@@ -0,0 +1,1177 @@
+#! /usr/bin/env python
+# -*- Mode: python; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# 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/.
+#
+
+"""
+This script generates precompiled headers for a given
+module and library.
+
+Given a gmake makefile that belongs to some LO module:
+1) Process the makefile to find source files (process_makefile).
+2) For every source file, find all includes (process_source).
+3) Uncommon and rare includes are filtered (remove_rare).
+4) Conflicting headers are excluded (filter_ignore).
+5) Local files to the source are excluded (Filter_Local).
+6) Fixup missing headers that sources expect (fixup).
+7) The resulting includes are sorted by category (sort_by_category).
+8) The pch file is generated (generate).
+"""
+
+import sys
+import re
+import os
+import unittest
+
+CUTOFF = 1
+EXCLUDE_MODULE = False
+EXCLUDE_LOCAL = False
+EXCLUDE_SYSTEM = True
+SILENT = False
+
+# System includes: oox, sal, sd, svl, vcl
+
+INCLUDE = False
+EXCLUDE = True
+DEFAULTS = \
+{
+# module.library : (min, system, module, local), best time
+ 'accessibility.acc' : ( 4, EXCLUDE, INCLUDE, INCLUDE), # 7.8
+ 'basctl.basctl' : ( 3, EXCLUDE, INCLUDE, EXCLUDE), # 11.9
+ 'basegfx.basegfx' : ( 3, EXCLUDE, EXCLUDE, INCLUDE), # 3.8
+ 'basic.sb' : ( 2, EXCLUDE, EXCLUDE, INCLUDE), # 10.7
+ 'chart2.chartcontroller' : ( 6, EXCLUDE, INCLUDE, INCLUDE), # 18.4
+ 'chart2.chartcore' : ( 3, EXCLUDE, EXCLUDE, INCLUDE), # 22.5
+ 'chart2.chartopengl' : (12, EXCLUDE, EXCLUDE, EXCLUDE), # 5.3
+ 'comphelper.comphelper' : ( 4, EXCLUDE, INCLUDE, INCLUDE), # 7.6
+ 'configmgr.configmgr' : ( 6, EXCLUDE, INCLUDE, INCLUDE), # 6.0
+ 'connectivity.ado' : ( 2, EXCLUDE, EXCLUDE, EXCLUDE), # 6.4
+ 'connectivity.calc' : ( 2, EXCLUDE, EXCLUDE, EXCLUDE), # 4.6
+ 'connectivity.dbase' : ( 2, EXCLUDE, INCLUDE, INCLUDE), # 5.2
+ 'connectivity.dbpool2' : ( 5, EXCLUDE, INCLUDE, EXCLUDE), # 3.0
+ 'connectivity.dbtools' : ( 2, EXCLUDE, EXCLUDE, INCLUDE), # 0.8
+ 'connectivity.file' : ( 2, EXCLUDE, INCLUDE, EXCLUDE), # 5.1
+ 'connectivity.firebird_sdbc' : ( 2, EXCLUDE, EXCLUDE, EXCLUDE), # 5.1
+ 'connectivity.flat' : ( 2, EXCLUDE, INCLUDE, INCLUDE), # 4.6
+ 'connectivity.mysql' : ( 4, EXCLUDE, INCLUDE, EXCLUDE), # 3.4
+ 'connectivity.odbc' : ( 2, EXCLUDE, EXCLUDE, INCLUDE), # 5.0
+ 'connectivity.postgresql-sdbc-impl' : ( 3, EXCLUDE, EXCLUDE, EXCLUDE), # 6.7
+ 'cppcanvas.cppcanvas' : (11, EXCLUDE, INCLUDE, INCLUDE), # 4.8
+ 'cppuhelper.cppuhelper' : ( 3, EXCLUDE, EXCLUDE, EXCLUDE), # 4.6
+ 'cui.cui' : ( 8, EXCLUDE, INCLUDE, EXCLUDE), # 19.7
+ 'dbaccess.dba' : ( 6, EXCLUDE, INCLUDE, INCLUDE), # 13.8
+ 'dbaccess.dbaxml' : ( 2, EXCLUDE, EXCLUDE, EXCLUDE), # 6.5
+ 'dbaccess.dbmm' : (10, EXCLUDE, INCLUDE, EXCLUDE), # 4.3
+ 'dbaccess.dbu' : (12, EXCLUDE, EXCLUDE, EXCLUDE), # 23.6
+ 'dbaccess.sdbt' : ( 1, EXCLUDE, INCLUDE, EXCLUDE), # 2.9
+ 'desktop.deployment' : ( 3, EXCLUDE, EXCLUDE, EXCLUDE), # 6.1
+ 'desktop.deploymentgui' : ( 3, EXCLUDE, EXCLUDE, EXCLUDE), # 5.7
+ 'desktop.deploymentmisc' : ( 3, EXCLUDE, EXCLUDE, EXCLUDE), # 3.4
+ 'desktop.sofficeapp' : ( 6, EXCLUDE, INCLUDE, INCLUDE), # 6.5
+ 'drawinglayer.drawinglayer' : ( 4, EXCLUDE, EXCLUDE, EXCLUDE), # 7.4
+ 'editeng.editeng' : ( 5, EXCLUDE, INCLUDE, EXCLUDE), # 13.0
+ 'forms.frm' : ( 2, EXCLUDE, EXCLUDE, EXCLUDE), # 14.2
+ 'framework.fwe' : (10, EXCLUDE, INCLUDE, EXCLUDE), # 5.5
+ 'framework.fwi' : ( 9, EXCLUDE, INCLUDE, EXCLUDE), # 3.4
+ 'framework.fwk' : ( 7, EXCLUDE, INCLUDE, INCLUDE), # 14.8
+ 'framework.fwl' : ( 5, EXCLUDE, INCLUDE, INCLUDE), # 5.1
+ 'hwpfilter.hwp' : ( 3, EXCLUDE, INCLUDE, INCLUDE), # 6.0
+ 'lotuswordpro.lwpft' : ( 2, EXCLUDE, EXCLUDE, EXCLUDE), # 11.6
+ 'oox.oox' : ( 6, EXCLUDE, EXCLUDE, INCLUDE), # 28.2
+ 'package.package2' : ( 3, EXCLUDE, INCLUDE, INCLUDE), # 4.5
+ 'package.xstor' : ( 2, EXCLUDE, INCLUDE, EXCLUDE), # 3.8
+ 'reportdesign.rpt' : ( 9, EXCLUDE, INCLUDE, INCLUDE), # 9.4
+ 'reportdesign.rptui' : ( 4, EXCLUDE, INCLUDE, INCLUDE), # 13.1
+ 'reportdesign.rptxml' : ( 2, EXCLUDE, EXCLUDE, INCLUDE), # 7.6
+ 'sal.sal' : ( 5, EXCLUDE, INCLUDE, INCLUDE), # 4.2
+ 'sc.sc' : (12, EXCLUDE, INCLUDE, INCLUDE), # 92.6
+ 'sc.scfilt' : ( 4, EXCLUDE, EXCLUDE, INCLUDE), # 39.9
+ 'sc.scui' : ( 1, EXCLUDE, EXCLUDE, INCLUDE), # 15.0
+ 'sc.vbaobj' : ( 1, EXCLUDE, EXCLUDE, INCLUDE), # 17.3
+ 'sd.sd' : ( 4, EXCLUDE, EXCLUDE, INCLUDE), # 47.4
+ 'sd.sdui' : ( 4, EXCLUDE, INCLUDE, INCLUDE), # 9.4
+ 'sdext.PresentationMinimizer' : ( 2, EXCLUDE, INCLUDE, INCLUDE), # 4.1
+ 'sdext.PresenterScreen' : ( 2, EXCLUDE, INCLUDE, EXCLUDE), # 7.1
+ 'sfx2.sfx' : ( 3, EXCLUDE, EXCLUDE, EXCLUDE), # 27.4
+ 'slideshow.slideshow' : ( 4, EXCLUDE, INCLUDE, EXCLUDE), # 10.8
+ 'sot.sot' : ( 5, EXCLUDE, EXCLUDE, INCLUDE), # 3.1
+ 'starmath.sm' : ( 5, EXCLUDE, EXCLUDE, INCLUDE), # 10.9
+ 'svgio.svgio' : ( 8, EXCLUDE, EXCLUDE, INCLUDE), # 4.3
+ 'svl.svl' : ( 6, EXCLUDE, EXCLUDE, EXCLUDE), # 7.6
+ 'svtools.svt' : ( 4, EXCLUDE, INCLUDE, EXCLUDE), # 17.6
+ 'svx.svx' : ( 3, EXCLUDE, EXCLUDE, INCLUDE), # 20.7
+ 'svx.svxcore' : ( 7, EXCLUDE, INCLUDE, EXCLUDE), # 37.0
+ 'sw.msword' : ( 4, EXCLUDE, INCLUDE, INCLUDE), # 22.4
+ 'sw.sw' : (11, EXCLUDE, EXCLUDE, INCLUDE), # 212.3
+ 'sw.swui' : ( 3, EXCLUDE, INCLUDE, INCLUDE), # 26.1
+ 'sw.vbaswobj' : ( 4, EXCLUDE, INCLUDE, INCLUDE), # 13.1
+ 'tools.tl' : ( 5, EXCLUDE, EXCLUDE, EXCLUDE), # 4.2
+ 'unotools.utl' : ( 3, EXCLUDE, EXCLUDE, INCLUDE), # 7.0
+ 'unoxml.unoxml' : ( 1, EXCLUDE, EXCLUDE, EXCLUDE), # 4.6
+ 'uui.uui' : ( 4, EXCLUDE, EXCLUDE, EXCLUDE), # 4.9
+ 'vbahelper.msforms' : ( 3, EXCLUDE, INCLUDE, INCLUDE), # 5.2
+ 'vbahelper.vbahelper' : ( 3, EXCLUDE, EXCLUDE, INCLUDE), # 7.0
+ 'vcl.vcl' : ( 6, EXCLUDE, INCLUDE, INCLUDE), # 35.7
+ 'writerfilter.writerfilter' : ( 3, EXCLUDE, EXCLUDE, INCLUDE), # 15.8
+ 'xmloff.xo' : ( 7, EXCLUDE, INCLUDE, INCLUDE), # 22.1
+ 'xmloff.xof' : ( 1, EXCLUDE, EXCLUDE, INCLUDE), # 4.4
+ 'xmlscript.xmlscript' : ( 4, EXCLUDE, EXCLUDE, INCLUDE), # 3.6
+ 'xmlsecurity.xmlsecurity' : ( 6, EXCLUDE, INCLUDE, INCLUDE), # 5.1
+ 'xmlsecurity.xsec_fw' : ( 2, EXCLUDE, INCLUDE, EXCLUDE), # 2.7
+ 'xmlsecurity.xsec_xmlsec' : ( 2, EXCLUDE, INCLUDE, INCLUDE), # 4.4
+}
+
+def remove_rare(raw, min_use=-1):
+ """ Remove headers not commonly included.
+ The minimum threshold is min_use.
+ """
+ # The minimum number of times a header
+ # must be included to be in the PCH.
+ min_use = min_use if min_use >= 0 else CUTOFF
+
+ out = []
+ if not raw or not len(raw):
+ return out
+
+ inc = sorted(raw)
+ last = inc[0]
+ count = 1
+ for x in range(1, len(inc)):
+ i = inc[x]
+ if i == last:
+ count += 1
+ else:
+ if count >= min_use:
+ out.append(last)
+ last = i
+ count = 1
+
+ # Last group.
+ if count >= min_use:
+ out.append(last)
+
+ return out
+
+def process_list(list, callable):
+ """ Given a list and callable
+ we pass each entry through
+ the callable and only add to
+ the output if not blank.
+ """
+ out = []
+ for i in list:
+ line = callable(i)
+ if line and len(line):
+ out.append(line)
+ return out
+
+def find_files(path, recurse=True):
+ list = []
+ for root, dir, files in os.walk(path):
+ list += map(lambda x: os.path.join(root, x), files)
+ return list
+
+def get_filename(line):
+ """ Strips the line from the
+ '#include' and angled brakets
+ and return the filename only.
+ """
+ if not len(line) or line[0] != '#':
+ return line
+ return re.sub(r'(.*#include\s*)<(.*)>(.*)', r'\2', line)
+
+def is_c_runtime(inc):
+ """ Heuristic-based detection of C/C++
+ runtime headers.
+ They are all-lowercase, with .h or
+ no extension, filename only.
+ """
+ inc = get_filename(inc)
+
+ if inc.endswith('.hxx') or inc.endswith('.hpp'):
+ return False
+
+ for c in inc:
+ if c == '/':
+ return False
+ if c == '.':
+ return inc.endswith('.h')
+ if c.isupper():
+ return False
+
+ return True
+
+def sanitize(raw):
+ """ There are two forms of includes,
+ those with <> and "".
+ Technically, the difference is that
+ the compiler can use an internal
+ representation for an angled include,
+ such that it doesn't have to be a file.
+ For our purposes, there is no difference.
+ Here, we convert everything to angled.
+ """
+ if not raw or not len(raw):
+ return ''
+ raw = raw.strip()
+ if not len(raw):
+ return ''
+ return re.sub(r'(.*#include\s*)\"(.*)\"(.*)', r'#include <\2>', raw)
+
+class Filter_Local(object):
+ """ Filter headers local to a module.
+ allow_public: allows include/module/file.hxx
+ #include <module/file.hxx>
+ allow_module: allows module/inc/file.hxx
+ #include <file.hxx>
+ allow_locals: allows module/source/file.hxx and
+ module/source/inc/file.hxx
+ #include <file.hxx>
+ """
+ def __init__(self, root, module, allow_public=True, allow_module=True, allow_locals=True):
+ self.root = root
+ self.module = module
+ self.allow_public = allow_public
+ self.allow_module = allow_module
+ self.allow_locals = allow_locals
+ self.public_prefix = '<' + self.module + '/'
+
+ all = find_files(os.path.join(root, module))
+ self.module = []
+ self.locals = []
+ mod_prefix = module + '/inc/'
+ for i in all:
+ if mod_prefix in i:
+ self.module.append(i)
+ else:
+ self.locals.append(i)
+
+ def is_public(self, line):
+ return self.public_prefix in line
+
+ def is_module(self, line):
+ """ Returns True if in module/inc/... """
+ filename = get_filename(line)
+ for i in self.module:
+ if i.endswith(filename):
+ return True
+ return False
+
+ def is_local(self, line):
+ """ Returns True if in module/source/... """
+ filename = get_filename(line)
+ for i in self.locals:
+ if i.endswith(filename):
+ return True
+ return False
+
+ def is_external(self, line):
+ return is_c_runtime(line) and \
+ not self.is_public(line) and \
+ not self.is_module(line) and \
+ not self.is_local(line)
+
+ def find_local_file(self, line):
+ """ Finds the header file in the module dir,
+ but doesn't validate.
+ """
+ filename = get_filename(line)
+ for i in self.locals:
+ if i.endswith(filename):
+ return i
+ for i in self.module:
+ if i.endswith(filename):
+ return i
+ return None
+
+ def proc(self, line):
+ assert line and len(line)
+ assert line[0] != '<' and line[0] != '#'
+
+ filename = get_filename(line)
+
+ # Local with relative path.
+ if filename.startswith('..'):
+ # Exclude for now as we don't have cxx path.
+ return ''
+
+ # Locals are included first (by the compiler).
+ if self.is_local(filename):
+ return line if self.allow_locals and '/inc/' in filename else ''
+
+ # Module headers are next.
+ if self.is_module(filename):
+ return line if self.allow_module else ''
+
+ # Public headers are last.
+ if self.is_public(line):
+ return line if self.allow_public else ''
+
+ # Leave out potentially unrelated files local
+ # to some other module we can't include directly.
+ if '/' not in filename and not self.is_external(filename):
+ return ''
+
+ # Unfiltered.
+ return line
+
+def filter_ignore(line, module):
+ """ Filters includes from known
+ problematic ones.
+ Expects sanitized input.
+ """
+ assert line and len(line)
+
+ # Always include files without extension.
+ if '.' not in line:
+ return line
+
+ # Extract filenames for ease of comparison.
+ line = get_filename(line)
+
+ # Filter out all files that are not normal headers.
+ if not line.endswith('.h') and \
+ not line.endswith('.hxx') and \
+ not line.endswith('.hpp') and \
+ not line.endswith('.hdl'):
+ return ''
+
+ ignore_list = [
+ 'LibreOfficeKit/LibreOfficeKitEnums.h', # Needs special directives
+ 'LibreOfficeKit/LibreOfficeKitTypes.h', # Needs special directives
+ 'jerror.h', # c++ unfriendly
+ 'jpeglib.h', # c++ unfriendly
+ 'svtools/editimplementation.hxx' # no direct include
+ ]
+
+ if module == 'accessibility':
+ ignore_list += [
+ # STR_SVT_ACC_LISTENTRY_SELCTED_STATE redefined from svtools.hrc
+ 'accessibility/extended/textwindowaccessibility.hxx',
+ ]
+ if module == 'basic':
+ ignore_list += [
+ 'basic/vbahelper.hxx',
+ ]
+ if module == 'connectivity':
+ ignore_list += [
+ 'com/sun/star/beans/PropertyAttribute.hpp', # OPTIONAL defined via objbase.h
+ 'com/sun/star/sdbcx/Privilege.hpp', # DELETE defined via objbase.h
+ ]
+ if module == 'reportdesign':
+ ignore_list += [
+ 'editeng/eeitemid.hxx', # macro redefined in ui/misc/UITools.cxx
+ ]
+ if module == 'sc':
+ ignore_list += [
+ 'progress.hxx', # special directives
+ 'scslots.hxx', # special directives
+ ]
+ if module == 'sd':
+ ignore_list += [
+ 'sdgslots.hxx', # special directives
+ 'sdslots.hxx', # special directives
+ 'svtools/sores.hxx', # redefines BMP_PLUGIN defined in svtools.hrc
+ ]
+ if module == 'sfx2':
+ ignore_list += [
+ 'sfx2/recentdocsview.hxx', # Redefines ApplicationType defined in objidl.h
+ 'sfx2/sidebar/Sidebar.hxx',
+ 'sfx2/sidebar/UnoSidebar.hxx',
+ 'sfxslots.hxx', # externally defined types
+ ]
+ if module == 'sot':
+ ignore_list += [
+ 'sysformats.hxx', # Windows headers
+ ]
+ if module == 'svx':
+ ignore_list += [
+ 'tbunosearchcontrollers.hxx', # Anonymous namespace
+ ]
+ if module == 'sw':
+ ignore_list += [
+ 'com/sun/star/ucb/NameClash.hpp', # conflicts with ERROR from Windows.h
+ ]
+ if module == 'vcl':
+ ignore_list += [
+ 'accmgr.hxx', # redefines ImplAccelList
+ 'image.h',
+ 'jobset.h',
+ 'opengl/gdiimpl.hxx',
+ 'opengl/salbmp.hxx',
+ 'openglgdiimpl', # ReplaceTextA
+ 'printdlg.hxx',
+ 'salinst.hxx', # GetDefaultPrinterA
+ 'salprn.hxx', # SetPrinterDataA
+ 'vcl/jobset.hxx',
+ 'vcl/oldprintadaptor.hxx',
+ 'vcl/opengl/OpenGLContext.hxx',
+ 'vcl/print.hxx',
+ 'vcl/prntypes.hxx', # redefines Orientation from filter/jpeg/Exif.hxx
+ 'vcl/sysdata.hxx',
+ ]
+ if module == 'xmloff':
+ ignore_list += [
+ 'SchXMLExport.hxx', # SchXMLAutoStylePoolP.hxx not found
+ 'SchXMLImport.hxx', # enums redefined in draw\sdxmlimp_impl.hxx
+ 'XMLEventImportHelper.hxx', # NameMap redefined in XMLEventExport.hxx
+ 'xmloff/XMLEventExport.hxx', # enums redefined
+ ]
+
+ for i in ignore_list:
+ if line.startswith(i):
+ return ''
+ if i[0] == '*' and line.endswith(i[1:]):
+ return ''
+ if i[-1] == '*' and line.startswith(i[:-1]):
+ return ''
+
+ return line
+
+def fixup(includes, module):
+ """ Here we add any headers
+ necessary in the pch.
+ These could be known to be very
+ common but for technical reasons
+ left out of the pch by this generator.
+ Or, they could be missing from the
+ source files where they are used
+ (probably because they had been
+ in the old pch, they were missed).
+ Also, these could be headers
+ that make the build faster but
+ aren't added automatically.
+ """
+ fixes = []
+ def append(inc):
+ # Add a space to exclude from
+ # ignore bisecting.
+ line = ' #include <{}>'.format(inc)
+ try:
+ i = fixes.index(inc)
+ fixes[i] = inc
+ except:
+ fixes.append(inc)
+
+ if module == 'basctl':
+ if 'basslots.hxx' in includes:
+ append('sfx2/msg.hxx')
+
+ #if module == 'sc':
+ # if 'scslots.hxx' in includes:
+ # append('sfx2/msg.hxx')
+ return fixes
+
+def sort_by_category(list, module, filter_local):
+ """ Move all 'system' headers first.
+ Core files of osl, rtl, sal, next.
+ Everything non-module-specific third.
+ Last, module-specific headers.
+ """
+ sys = []
+ boo = []
+ cor = []
+ rst = []
+ mod = []
+
+ prefix = '<' + module + '/'
+ for i in list:
+ if is_c_runtime(i):
+ sys.append(i)
+ elif '<boost/' in i:
+ boo.append(i)
+ elif '<osl' in i or '<rtl' in i or '<sal' in i or '<vcl' in i:
+ cor.append(i)
+ elif prefix in i:
+ mod.append(i)
+ else:
+ rst.append(i)
+
+ out = []
+ out += sorted(sys)
+ out += sorted(boo)
+ out += sorted(cor)
+ out += sorted(rst)
+ out += sorted(mod)
+ return out
+
+def parse_makefile(groups, lines, lineno, lastif, ifstack):
+
+ inobjects = False
+ inelse = False
+ os_cond_re = re.compile('(ifeq|ifneq)\s*\(\$\(OS\)\,(\w*)\)')
+
+ line = lines[lineno]
+ if line.startswith('if'):
+ lastif = line
+ if ifstack == 0:
+ # Correction if first line is an if.
+ lineno = parse_makefile(groups, lines, lineno, line, ifstack+1)
+ else:
+ lineno -= 1
+
+ while lineno + 1 < len(lines):
+ lineno += 1
+ line = lines[lineno].strip()
+ line = line.rstrip('\\').strip()
+ #print('line #{}: {}'.format(lineno, line))
+ if len(line) == 0:
+ continue
+
+ if line == '))':
+ inobjects = False
+ elif 'add_exception_objects' in line or \
+ 'add_cxxobject' in line:
+ inobjects = True
+ #print('inobjects')
+ #if ifstack and not SILENT:
+ #sys.stderr.write('Sources in a conditional, ignoring for now.\n')
+ elif line.startswith('if'):
+ lineno = parse_makefile(groups, lines, lineno, line, ifstack+1)
+ continue
+ elif line.startswith('endif'):
+ if ifstack:
+ return lineno
+ continue
+ elif line.startswith('else'):
+ inelse = True
+ elif inobjects:
+ if EXCLUDE_SYSTEM and ifstack:
+ continue
+ file = line + '.cxx'
+ if ',' in line or '(' in line or ')' in line:
+ #print('passing: ' + line)
+ pass # $if() probably, or something similar
+ else:
+ osname = ''
+ if lastif:
+ if 'filter' in lastif:
+ # We can't grok filter, yet.
+ continue
+ match = os_cond_re.match(lastif)
+ if not match:
+ # We only support OS conditionals.
+ continue
+ in_out = match.group(1)
+ osname = match.group(2) if match else ''
+ if (in_out == 'ifneq' and not inelse) or \
+ (in_out == 'ifeq' and inelse):
+ osname = '!' + osname
+
+ if osname not in groups:
+ groups[osname] = []
+ groups[osname].append(file)
+
+ return groups
+
+def process_makefile(root, module, makefile):
+ """ Parse a gmake makefile and extract
+ source filenames from it.
+ """
+
+ filename = os.path.join(os.path.join(root, module), makefile)
+ if not os.path.isfile(filename):
+ sys.stderr.write('Error: Module {} has no makefile at {}.'.format(module, filename))
+