[Libreoffice-commits] core.git: Branch 'private/kohei/xlsx-import-speedup' - 237 commits - android/CustomTarget_android_desktop.mk android/CustomTarget_lo4android.mk android/CustomTarget_sdremote.mk basctl/source basegfx/test basic/source bin/get-bugzilla-attachments-by-mimetype bin/lo-generate-source-tarball bin/verify-custom-widgets-libs canvas/source chart2/source comphelper/source config_host/config_oauth2.h.in config_host.mk.in configure.ac connectivity/CppunitTest_connectivity_commontools.mk connectivity/Library_dbase.mk connectivity/Library_dbtools.mk connectivity/Library_firebird_sdbc.mk connectivity/qa connectivity/source connectivity/workben cppuhelper/source cppuhelper/test cpputools/source crashrep/Executable_crashrep.mk cui/source dbaccess/CppunitTest_dbaccess_dialog_save.mk dbaccess/CppunitTest_dbaccess_firebird_test.mk dbaccess/CppunitTest_dbaccess_macros_test.mk dbaccess/Module_dbaccess.mk dbaccess/qa dbaccess/source desktop/source download.lst dtrans/source editeng/source embeddedobj/source embedserv/source eventattacher/source extensions/source external/icu external/libebook external/libexttextcat external/Module_external.mk filter/Configuration_filter.mk filter/source forms/source formula/source fpicker/source framework/source helpcompiler/source helpcontent2 hwpfilter/qa i18nlangtag/source i18npool/Library_localedata_others.mk i18npool/qa i18npool/source i18nutil/source idlc/source idl/inc idl/source include/apple_remote include/avmedia include/basebmp include/basic include/canvas include/codemaker include/com include/comphelper include/connectivity include/cppu include/cppuhelper include/dbaccess include/drawinglayer include/editeng include/filter include/formula include/framework include/helpcompiler include/i18nlangtag include/i18nutil include/jvmaccess include/jvmfwk include/linguistic include/oox include/osl include/package include/registry include/rtl include/sal include/salhelper include/sax include/sfx2 include/shell include/sot i nclude/store include/svl include/svtools include/svx include/test include/toolkit include/tools include/ucbhelper include/uno include/unoidl include/unotest include/unotools include/vbahelper include/vcl include/xmloff include/xmlreader include/xmlscript instsetoo_native/util ios/experimental ios/Module_ios.mk io/source io/test jvmfwk/plugins jvmfwk/source lingucomponent/source linguistic/source linguistic/workben lotuswordpro/source Makefile.fetch Makefile.in mysqlc/source odk/examples odk/Package_share_readme.mk offapi/com officecfg/Configuration_officecfg.mk officecfg/registry oox/source package/source padmin/source postprocess/CustomTarget_images.mk postprocess/CustomTarget_registry.mk pyuno/source readlicense_oo/CustomTarget_license.mk readlicense_oo/html readlicense_oo/license readlicense_oo/odt readlicense_oo/Package_files.mk readlicense_oo/txt registry/workben remotebridges/examples reportdesign/source RepositoryExternal.mk Repository.mk sal/qa sax/source scaddins/so urce sccomp/source sc/CppunitTest_sc_chart_regression_test.mk sc/inc scp2/source sc/qa scripting/source sc/source sdext/source sd/source sfx2/inc sfx2/source sfx2/uiconfig shell/source slideshow/source smoketest/Executable_libtest.mk smoketest/libtest.cxx smoketest/smoketest.cxx solenv/bin solenv/doc solenv/gbuild sot/source starmath/source stoc/source stoc/test store/workben svl/source svtools/inc svtools/source svx/source sw/inc sw/qa sw/source test/Library_subsequenttest.mk test/source testtools/source toolkit/source tools/qa tubes/source ucb/source ucb/workben unodevtools/source unotest/source unotools/source unoxml/source uui/source vbahelper/source vcl/aqua vcl/generic vcl/inc vcl/source vcl/unx vcl/win writerfilter/inc writerfilter/source writerperfect/Library_wpftwriter.mk writerperfect/source writerperfect/util xmlhelp/source xmloff/inc xmloff/source xmlsecurity/source

Kohei Yoshida kohei.yoshida at collabora.com
Mon Nov 11 11:48:22 PST 2013


Rebased ref, commits from common ancestor:
commit 2dce8b2e1e4e452a9eaa057300cbe9ec9de293bd
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Mon Nov 11 11:26:30 2013 -0500

    Add test for importing some of those functions new in Excel 2010.
    
    Change-Id: Ic3577b3ef0edcfa417ae0065499171bf770c2a32

diff --git a/sc/qa/unit/data/xlsx/functions-excel-2010.xlsx b/sc/qa/unit/data/xlsx/functions-excel-2010.xlsx
new file mode 100755
index 0000000..03e570e
Binary files /dev/null and b/sc/qa/unit/data/xlsx/functions-excel-2010.xlsx differ
diff --git a/sc/qa/unit/helper/qahelper.cxx b/sc/qa/unit/helper/qahelper.cxx
index 905abef..23b45c8 100644
--- a/sc/qa/unit/helper/qahelper.cxx
+++ b/sc/qa/unit/helper/qahelper.cxx
@@ -430,6 +430,15 @@ bool checkFormula(ScDocument& rDoc, const ScAddress& rPos, const char* pExpected
     return true;
 }
 
+bool isFormulaWithoutError(ScDocument& rDoc, const ScAddress& rPos)
+{
+    ScFormulaCell* pFC = rDoc.GetFormulaCell(rPos);
+    if (!pFC)
+        return false;
+
+    return pFC->GetErrCode() == 0;
+}
+
 OUString toString(
     ScDocument& rDoc, const ScAddress& rPos, ScTokenArray& rArray, formula::FormulaGrammar::Grammar eGram)
 {
diff --git a/sc/qa/unit/helper/qahelper.hxx b/sc/qa/unit/helper/qahelper.hxx
index a6d5a02..657f66b 100644
--- a/sc/qa/unit/helper/qahelper.hxx
+++ b/sc/qa/unit/helper/qahelper.hxx
@@ -121,6 +121,12 @@ SCQAHELPER_DLLPUBLIC ScRangeList getChartRanges(ScDocument& rDoc, const SdrOle2O
 SCQAHELPER_DLLPUBLIC bool checkFormula(ScDocument& rDoc, const ScAddress& rPos, const char* pExpected);
 
 /**
+ * Check if the cell at specified position is a formula cell that doesn't
+ * have an error value.
+ */
+SCQAHELPER_DLLPUBLIC bool isFormulaWithoutError(ScDocument& rDoc, const ScAddress& rPos);
+
+/**
  * Convert formula token array to a formula string.
  */
 SCQAHELPER_DLLPUBLIC OUString toString(
diff --git a/sc/qa/unit/subsequent_filters-test.cxx b/sc/qa/unit/subsequent_filters-test.cxx
index 4f7d702..b2dc2b6 100644
--- a/sc/qa/unit/subsequent_filters-test.cxx
+++ b/sc/qa/unit/subsequent_filters-test.cxx
@@ -87,6 +87,7 @@ public:
     void testRangeNameXLSX();
     void testHardRecalcODS();
     void testFunctionsODS();
+    void testFunctionsExcel2010();
     void testCachedFormulaResultsODS();
     void testCachedMatrixFormulaResultsODS();
     void testDatabaseRangesODS();
@@ -155,6 +156,7 @@ public:
     CPPUNIT_TEST(testRangeNameXLSX);
     CPPUNIT_TEST(testHardRecalcODS);
     CPPUNIT_TEST(testFunctionsODS);
+    CPPUNIT_TEST(testFunctionsExcel2010);
     CPPUNIT_TEST(testCachedFormulaResultsODS);
     CPPUNIT_TEST(testCachedMatrixFormulaResultsODS);
     CPPUNIT_TEST(testDatabaseRangesODS);
@@ -371,6 +373,27 @@ void ScFiltersTest::testFunctionsODS()
     xDocSh->DoClose();
 }
 
+void ScFiltersTest::testFunctionsExcel2010()
+{
+    ScDocShellRef xDocSh = loadDoc("functions-excel-2010.", XLSX);
+    CPPUNIT_ASSERT_MESSAGE("Failed to load the document.", xDocSh.Is());
+    ScDocument* pDoc = xDocSh->GetDocument();
+    pDoc->CalcAll(); // perform hard re-calculation.
+
+    // B2:B6 and B8 should all be formula cells, and shouldn't have errors.
+    CPPUNIT_ASSERT_MESSAGE("Expected a formula cell without errro.", isFormulaWithoutError(*pDoc, ScAddress(1,1,0)));
+    CPPUNIT_ASSERT_MESSAGE("Expected a formula cell without errro.", isFormulaWithoutError(*pDoc, ScAddress(1,2,0)));
+    CPPUNIT_ASSERT_MESSAGE("Expected a formula cell without errro.", isFormulaWithoutError(*pDoc, ScAddress(1,3,0)));
+    CPPUNIT_ASSERT_MESSAGE("Expected a formula cell without errro.", isFormulaWithoutError(*pDoc, ScAddress(1,4,0)));
+#if 0 // CHISQ.TEST and F.DIST.RT are not yet supported in the core.
+    CPPUNIT_ASSERT_MESSAGE("Expected a formula cell without errro.", isFormulaWithoutError(*pDoc, ScAddress(1,5,0)));
+    // Skip B7.
+    CPPUNIT_ASSERT_MESSAGE("Expected a formula cell without errro.", isFormulaWithoutError(*pDoc, ScAddress(1,7,0)));
+#endif
+
+    xDocSh->DoClose();
+}
+
 void ScFiltersTest::testCachedFormulaResultsODS()
 {
     {
commit 977cbc6af9586c3adf910898550c0da1e1a868d8
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Mon Nov 11 17:07:35 2013 +0000

    Accelerate checking for VBA macros that are not there.

diff --git a/offapi/com/sun/star/script/vba/XVBAEventProcessor.idl b/offapi/com/sun/star/script/vba/XVBAEventProcessor.idl
index 750cc4d..1fbf75d 100644
--- a/offapi/com/sun/star/script/vba/XVBAEventProcessor.idl
+++ b/offapi/com/sun/star/script/vba/XVBAEventProcessor.idl
@@ -44,10 +44,7 @@ interface XVBAEventProcessor
 
         @return
             `TRUE`, if the VBA event handler exists.
-
-        @throws ::com::sun::star::lang::IllegalArgumentException
-            if the passed event identifier is not supported, or if the passed
-            specifier is required but invalid.
+            `FALSE`, for all other cases.
     **/
     boolean hasVbaEventHandler( [in] long nEventId, [in] sequence< any > aArgs )
         raises (::com::sun::star::lang::IllegalArgumentException);
diff --git a/vbahelper/source/vbahelper/vbaeventshelperbase.cxx b/vbahelper/source/vbahelper/vbaeventshelperbase.cxx
index b6a7e7a..69b5584 100644
--- a/vbahelper/source/vbahelper/vbaeventshelperbase.cxx
+++ b/vbahelper/source/vbahelper/vbaeventshelperbase.cxx
@@ -51,15 +51,6 @@ VbaEventsHelperBase::~VbaEventsHelperBase()
     SAL_WARN_IF( !mbDisposed, "vbahelper", "VbaEventsHelperBase::~VbaEventsHelperBase - missing disposing notification" );
 }
 
-sal_Bool SAL_CALL VbaEventsHelperBase::hasVbaEventHandler( sal_Int32 nEventId, const uno::Sequence< uno::Any >& rArgs )
-        throw (lang::IllegalArgumentException, uno::RuntimeException)
-{
-    // getEventHandlerInfo() throws, if unknown event dentifier has been passed
-    const EventHandlerInfo& rInfo = getEventHandlerInfo( nEventId );
-    // getEventHandlerPath() searches for the macro in the document
-    return !getEventHandlerPath( rInfo, rArgs ).isEmpty();
-}
-
 sal_Bool SAL_CALL VbaEventsHelperBase::processVbaEvent( sal_Int32 nEventId, const uno::Sequence< uno::Any >& rArgs )
         throw (lang::IllegalArgumentException, util::VetoException, uno::RuntimeException)
 {
@@ -241,6 +232,16 @@ void VbaEventsHelperBase::stopListening()
     mbDisposed = true;
 }
 
+sal_Bool SAL_CALL VbaEventsHelperBase::hasVbaEventHandler( sal_Int32 nEventId, const uno::Sequence< uno::Any >& rArgs )
+        throw (lang::IllegalArgumentException, uno::RuntimeException)
+{
+    EventHandlerInfoMap::const_iterator aIt = maEventInfos.find( nEventId );
+    if( aIt == maEventInfos.end() )
+        return sal_False; // throwing a lot of exceptions is slow.
+    else // getEventHandlerPath() searches for the macro in the document
+        return !getEventHandlerPath( aIt->second, rArgs ).isEmpty();
+}
+
 const VbaEventsHelperBase::EventHandlerInfo& VbaEventsHelperBase::getEventHandlerInfo(
         sal_Int32 nEventId ) const throw (lang::IllegalArgumentException)
 {
commit bcabc0563e576109848007e0c99053f999105451
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Sat Nov 9 00:01:49 2013 -0500

    Add separate list of function names for OOXML import.
    
    Change-Id: Id6bb9ed65f94a56e82c0c4a6fee241dec4eb9138

diff --git a/formula/source/core/api/FormulaCompiler.cxx b/formula/source/core/api/FormulaCompiler.cxx
index f54d00b..1d84757 100644
--- a/formula/source/core/api/FormulaCompiler.cxx
+++ b/formula/source/core/api/FormulaCompiler.cxx
@@ -703,7 +703,7 @@ void FormulaCompiler::InitSymbolsEnglishXL() const
     static OpCodeMapData aMap;
     osl::MutexGuard aGuard(&aMap.maMtx);
     if (!aMap.mxSymbolMap)
-        loadSymbols(RID_STRLIST_FUNCTION_NAMES_ENGLISH, FormulaGrammar::GRAM_ENGLISH, aMap.mxSymbolMap);
+        loadSymbols(RID_STRLIST_FUNCTION_NAMES_ENGLISH_OOXML, FormulaGrammar::GRAM_ENGLISH, aMap.mxSymbolMap);
     mxSymbolsEnglishXL = aMap.mxSymbolMap;
 
     // TODO: For now, just replace the separators to the Excel English
diff --git a/formula/source/core/inc/core_resource.hrc b/formula/source/core/inc/core_resource.hrc
index 3594989..5253e65 100644
--- a/formula/source/core/inc/core_resource.hrc
+++ b/formula/source/core/inc/core_resource.hrc
@@ -29,8 +29,9 @@
 //------------------------------------------------------------------------------
 //- String-IDs
 #define RID_STRLIST_FUNCTION_NAMES_ENGLISH_ODFF     (RID_CORE_OTHER_START + 0)
-#define RID_STRLIST_FUNCTION_NAMES_ENGLISH          (RID_CORE_OTHER_START + 1)
-#define RID_STRLIST_FUNCTION_NAMES                  (RID_CORE_OTHER_START + 2)
+#define RID_STRLIST_FUNCTION_NAMES_ENGLISH_OOXML    (RID_CORE_OTHER_START + 1)
+#define RID_STRLIST_FUNCTION_NAMES_ENGLISH          (RID_CORE_OTHER_START + 2)
+#define RID_STRLIST_FUNCTION_NAMES                  (RID_CORE_OTHER_START + 3)
 
 
 #endif // _FORMULA_CORE_RESOURCE_HRC_
diff --git a/formula/source/core/resource/core_resource.src b/formula/source/core/resource/core_resource.src
index f67ac77..06e39e7 100644
--- a/formula/source/core/resource/core_resource.src
+++ b/formula/source/core/resource/core_resource.src
@@ -382,6 +382,362 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH_ODFF
     String SC_OPCODE_WEBSERVICE    { Text = "COM.MICROSOFT.WEBSERVICE"; };
 };
 
+Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH_OOXML
+{
+    String SC_OPCODE_IF { Text = "IF" ; };
+    String SC_OPCODE_IF_ERROR { Text = "IFERROR" ; };
+    String SC_OPCODE_IF_NA { Text = "IFNA" ; };
+    String SC_OPCODE_CHOSE { Text = "CHOOSE" ; };
+    String SC_OPCODE_OPEN { Text = "(" ; };
+    String SC_OPCODE_CLOSE { Text = ")" ; };
+    String SC_OPCODE_ARRAY_OPEN { Text = "{" ; };
+    String SC_OPCODE_ARRAY_CLOSE { Text = "}" ; };
+    String SC_OPCODE_ARRAY_ROW_SEP { Text = ";" ; };
+    String SC_OPCODE_ARRAY_COL_SEP { Text = "," ; };
+    String SC_OPCODE_SEP { Text = "," ; };
+    String SC_OPCODE_PERCENT_SIGN { Text = "%" ; };
+    String SC_OPCODE_ADD { Text = "+" ; };
+    String SC_OPCODE_SUB { Text = "-" ; };
+    String SC_OPCODE_MUL { Text = "*" ; };
+    String SC_OPCODE_DIV { Text = "/" ; };
+    String SC_OPCODE_AMPERSAND { Text = "&" ; };
+    String SC_OPCODE_POW { Text = "^" ; };
+    String SC_OPCODE_EQUAL { Text = "=" ; };
+    String SC_OPCODE_NOT_EQUAL { Text = "<>" ; };
+    String SC_OPCODE_LESS { Text = "<" ; };
+    String SC_OPCODE_GREATER { Text = ">" ; };
+    String SC_OPCODE_LESS_EQUAL { Text = "<=" ; };
+    String SC_OPCODE_GREATER_EQUAL { Text = ">=" ; };
+    String SC_OPCODE_AND { Text = "AND" ; };
+    String SC_OPCODE_OR { Text = "OR" ; };
+    String SC_OPCODE_XOR { Text = "XOR" ; };
+    String SC_OPCODE_INTERSECT { Text = "!" ; };
+    String SC_OPCODE_UNION { Text = "~" ; };
+    String SC_OPCODE_RANGE { Text = ":" ; };
+    String SC_OPCODE_NOT { Text = "NOT" ; };
+    String SC_OPCODE_NEG { Text = "NEG" ; };
+    String SC_OPCODE_NEG_SUB { Text = "-" ; };
+    String SC_OPCODE_PI { Text = "PI" ; };
+    String SC_OPCODE_RANDOM { Text = "RAND" ; };
+    String SC_OPCODE_TRUE { Text = "TRUE" ; };
+    String SC_OPCODE_FALSE { Text = "FALSE" ; };
+    String SC_OPCODE_GET_ACT_DATE { Text = "TODAY" ; };
+    String SC_OPCODE_GET_ACT_TIME { Text = "NOW" ; };
+    String SC_OPCODE_NO_VALUE { Text = "NA" ; };
+    String SC_OPCODE_CURRENT { Text = "CURRENT" ; };
+    String SC_OPCODE_DEG { Text = "DEGREES" ; };
+    String SC_OPCODE_RAD { Text = "RADIANS" ; };
+    String SC_OPCODE_SIN { Text = "SIN" ; };
+    String SC_OPCODE_COS { Text = "COS" ; };
+    String SC_OPCODE_TAN { Text = "TAN" ; };
+    String SC_OPCODE_COT { Text = "COT" ; };
+    String SC_OPCODE_ARC_SIN { Text = "ASIN" ; };
+    String SC_OPCODE_ARC_COS { Text = "ACOS" ; };
+    String SC_OPCODE_ARC_TAN { Text = "ATAN" ; };
+    String SC_OPCODE_ARC_COT { Text = "ACOT" ; };
+    String SC_OPCODE_SIN_HYP { Text = "SINH" ; };
+    String SC_OPCODE_COS_HYP { Text = "COSH" ; };
+    String SC_OPCODE_TAN_HYP { Text = "TANH" ; };
+    String SC_OPCODE_COT_HYP { Text = "COTH" ; };
+    String SC_OPCODE_ARC_SIN_HYP { Text = "ASINH" ; };
+    String SC_OPCODE_ARC_COS_HYP { Text = "ACOSH" ; };
+    String SC_OPCODE_ARC_TAN_HYP { Text = "ATANH" ; };
+    String SC_OPCODE_ARC_COT_HYP { Text = "ACOTH" ; };
+    String SC_OPCODE_COSECANT { Text = "CSC" ; };
+    String SC_OPCODE_SECANT { Text = "SEC" ; };
+    String SC_OPCODE_COSECANT_HYP { Text = "CSCH" ; };
+    String SC_OPCODE_SECANT_HYP { Text = "SECH" ; };
+    String SC_OPCODE_EXP { Text = "EXP" ; };
+    String SC_OPCODE_LN { Text = "LN" ; };
+    String SC_OPCODE_SQRT { Text = "SQRT" ; };
+    String SC_OPCODE_FACT { Text = "FACT" ; };
+    String SC_OPCODE_GET_YEAR { Text = "YEAR" ; };
+    String SC_OPCODE_GET_MONTH { Text = "MONTH" ; };
+    String SC_OPCODE_GET_DAY { Text = "DAY" ; };
+    String SC_OPCODE_GET_HOUR { Text = "HOUR" ; };
+    String SC_OPCODE_GET_MIN { Text = "MINUTE" ; };
+    String SC_OPCODE_GET_SEC { Text = "SECOND" ; };
+    String SC_OPCODE_PLUS_MINUS { Text = "SIGN" ; };
+    String SC_OPCODE_ABS { Text = "ABS" ; };
+    String SC_OPCODE_INT { Text = "INT" ; };
+    String SC_OPCODE_PHI { Text = "PHI" ; };
+    String SC_OPCODE_GAUSS { Text = "GAUSS" ; };
+    String SC_OPCODE_IS_EMPTY { Text = "ISBLANK" ; };
+    String SC_OPCODE_IS_STRING { Text = "ISTEXT" ; };
+    String SC_OPCODE_IS_NON_STRING { Text = "ISNONTEXT" ; };
+    String SC_OPCODE_IS_LOGICAL { Text = "ISLOGICAL" ; };
+    String SC_OPCODE_TYPE { Text = "TYPE" ; };
+    String SC_OPCODE_CELL { Text = "CELL" ; };
+    String SC_OPCODE_IS_REF { Text = "ISREF" ; };
+    String SC_OPCODE_IS_VALUE { Text = "ISNUMBER" ; };
+    String SC_OPCODE_IS_FORMULA { Text = "ISFORMULA" ; };
+    String SC_OPCODE_IS_NV { Text = "ISNA" ; };
+    String SC_OPCODE_IS_ERR { Text = "ISERR" ; };
+    String SC_OPCODE_IS_ERROR { Text = "ISERROR" ; };
+    String SC_OPCODE_IS_EVEN { Text = "ISEVEN" ; };
+    String SC_OPCODE_IS_ODD { Text = "ISODD" ; };
+    String SC_OPCODE_N { Text = "N" ; };
+    String SC_OPCODE_GET_DATE_VALUE { Text = "DATEVALUE" ; };
+    String SC_OPCODE_GET_TIME_VALUE { Text = "TIMEVALUE" ; };
+    String SC_OPCODE_CODE { Text = "CODE" ; };
+    String SC_OPCODE_TRIM { Text = "TRIM" ; };
+    String SC_OPCODE_UPPER { Text = "UPPER" ; };
+    String SC_OPCODE_PROPPER { Text = "PROPER" ; };
+    String SC_OPCODE_LOWER { Text = "LOWER" ; };
+    String SC_OPCODE_LEN { Text = "LEN" ; };
+    String SC_OPCODE_T { Text = "T" ; };
+    String SC_OPCODE_VALUE { Text = "VALUE" ; };
+    String SC_OPCODE_CLEAN { Text = "CLEAN" ; };
+    String SC_OPCODE_CHAR { Text = "CHAR" ; };
+    String SC_OPCODE_JIS { Text = "JIS" ; };
+    String SC_OPCODE_ASC { Text = "ASC" ; };
+    String SC_OPCODE_UNICODE { Text = "UNICODE" ; };
+    String SC_OPCODE_UNICHAR { Text = "UNICHAR" ; };
+    String SC_OPCODE_LOG10 { Text = "LOG10" ; };
+    String SC_OPCODE_EVEN { Text = "EVEN" ; };
+    String SC_OPCODE_ODD { Text = "ODD" ; };
+    String SC_OPCODE_STD_NORM_DIST { Text = "NORMSDIST" ; };
+    String SC_OPCODE_FISHER { Text = "FISHER" ; };
+    String SC_OPCODE_FISHER_INV { Text = "FISHERINV" ; };
+    String SC_OPCODE_S_NORM_INV { Text = "NORMSINV" ; };
+    String SC_OPCODE_GAMMA_LN { Text = "GAMMALN" ; };
+    String SC_OPCODE_ERROR_TYPE { Text = "ERRORTYPE" ; };
+    String SC_OPCODE_ERR_CELL { Text = "ZellError" ; };  // TODO: ancient legacy only, remove?
+    String SC_OPCODE_FORMULA { Text = "FORMULA"; };
+    String SC_OPCODE_ARC_TAN_2 { Text = "ATAN2" ; };
+    String SC_OPCODE_CEIL { Text = "CEILING" ; };
+    String SC_OPCODE_FLOOR { Text = "FLOOR" ; };
+    String SC_OPCODE_ROUND { Text = "ROUND" ; };
+    String SC_OPCODE_ROUND_UP { Text = "ROUNDUP" ; };
+    String SC_OPCODE_ROUND_DOWN { Text = "ROUNDDOWN" ; };
+    String SC_OPCODE_TRUNC { Text = "TRUNC" ; };
+    String SC_OPCODE_LOG { Text = "LOG" ; };
+    String SC_OPCODE_POWER { Text = "POWER" ; };
+    String SC_OPCODE_GGT { Text = "GCD" ; };
+    String SC_OPCODE_KGV { Text = "LCM" ; };
+    String SC_OPCODE_MOD { Text = "MOD" ; };
+    String SC_OPCODE_SUM_PRODUCT { Text = "SUMPRODUCT" ; };
+    String SC_OPCODE_SUM_SQ { Text = "SUMSQ" ; };
+    String SC_OPCODE_SUM_X2MY2 { Text = "SUMX2MY2" ; };
+    String SC_OPCODE_SUM_X2DY2 { Text = "SUMX2PY2" ; };
+    String SC_OPCODE_SUM_XMY2 { Text = "SUMXMY2" ; };
+    String SC_OPCODE_GET_DATE { Text = "DATE" ; };
+    String SC_OPCODE_GET_TIME { Text = "TIME" ; };
+    String SC_OPCODE_GET_DIFF_DATE { Text = "DAYS" ; };
+    String SC_OPCODE_GET_DIFF_DATE_360 { Text = "DAYS360" ; };
+    String SC_OPCODE_GET_DATEDIF { Text = "DATEDIF" ; };
+    String SC_OPCODE_MIN { Text = "MIN" ; };
+    String SC_OPCODE_MIN_A { Text = "MINA" ; };
+    String SC_OPCODE_MAX { Text = "MAX" ; };
+    String SC_OPCODE_MAX_A { Text = "MAXA" ; };
+    String SC_OPCODE_SUM { Text = "SUM" ; };
+    String SC_OPCODE_PRODUCT { Text = "PRODUCT" ; };
+    String SC_OPCODE_AVERAGE { Text = "AVERAGE" ; };
+    String SC_OPCODE_AVERAGE_A { Text = "AVERAGEA" ; };
+    String SC_OPCODE_COUNT { Text = "COUNT" ; };
+    String SC_OPCODE_COUNT_2 { Text = "COUNTA" ; };
+    String SC_OPCODE_NBW { Text = "NPV" ; };
+    String SC_OPCODE_IKV { Text = "IRR" ; };
+    String SC_OPCODE_MIRR { Text = "MIRR" ; };
+    String SC_OPCODE_ISPMT { Text = "ISPMT" ; };
+    String SC_OPCODE_VAR { Text = "VAR" ; };
+    String SC_OPCODE_VAR_A { Text = "VARA" ; };
+    String SC_OPCODE_VAR_P { Text = "VARP" ; };
+    String SC_OPCODE_VAR_P_A { Text = "VARPA" ; };
+    String SC_OPCODE_VAR_P_MS { Text = "VAR.P" ; };
+    String SC_OPCODE_VAR_S { Text = "VAR.S" ; };
+    String SC_OPCODE_ST_DEV { Text = "STDEV" ; };
+    String SC_OPCODE_ST_DEV_A { Text = "STDEVA" ; };
+    String SC_OPCODE_ST_DEV_P { Text = "STDEVP" ; };
+    String SC_OPCODE_ST_DEV_P_A { Text = "STDEVPA" ; };
+    String SC_OPCODE_ST_DEV_P_MS { Text = "STDEV.P" ; };
+    String SC_OPCODE_ST_DEV_S { Text = "STDEV.S" ; };
+    String SC_OPCODE_B { Text = "B" ; };
+    String SC_OPCODE_NORM_DIST { Text = "NORMDIST" ; };
+    String SC_OPCODE_EXP_DIST { Text = "EXPONDIST" ; };
+    String SC_OPCODE_BINOM_DIST { Text = "BINOMDIST" ; };
+    String SC_OPCODE_BINOM_DIST_MS { Text = "_xlfn.BINOM.DIST" ; };
+    String SC_OPCODE_POISSON_DIST { Text = "POISSON" ; };
+    String SC_OPCODE_KOMBIN { Text = "COMBIN" ; };
+    String SC_OPCODE_KOMBIN_2 { Text = "COMBINA" ; };
+    String SC_OPCODE_VARIATIONEN { Text = "PERMUT" ; };
+    String SC_OPCODE_VARIATIONEN_2 { Text = "PERMUTATIONA" ; };
+    String SC_OPCODE_BW { Text = "PV" ; };
+    String SC_OPCODE_DIA { Text = "SYD" ; };
+    String SC_OPCODE_GDA { Text = "DDB" ; };
+    String SC_OPCODE_GDA_2 { Text = "DB" ; };
+    String SC_OPCODE_VBD { Text = "VDB" ; };
+    String SC_OPCODE_LAUFZ { Text = "DURATION" ; };
+    String SC_OPCODE_LIA { Text = "SLN" ; };
+    String SC_OPCODE_RMZ { Text = "PMT" ; };
+    String SC_OPCODE_COLUMNS { Text = "COLUMNS" ; };
+    String SC_OPCODE_ROWS { Text = "ROWS" ; };
+    String SC_OPCODE_TABLES { Text = "SHEETS" ; };
+    String SC_OPCODE_COLUMN { Text = "COLUMN" ; };
+    String SC_OPCODE_ROW { Text = "ROW" ; };
+    String SC_OPCODE_TABLE { Text = "SHEET" ; };
+    String SC_OPCODE_ZGZ { Text = "ZGZ" ; };
+    String SC_OPCODE_ZW { Text = "FV" ; };
+    String SC_OPCODE_ZZR { Text = "NPER" ; };
+    String SC_OPCODE_ZINS { Text = "RATE" ; };
+    String SC_OPCODE_ZINS_Z { Text = "IPMT" ; };
+    String SC_OPCODE_KAPZ { Text = "PPMT" ; };
+    String SC_OPCODE_KUM_ZINS_Z { Text = "CUMIPMT" ; };
+    String SC_OPCODE_KUM_KAP_Z { Text = "CUMPRINC" ; };
+    String SC_OPCODE_EFFEKTIV { Text = "EFFECTIVE" ; };
+    String SC_OPCODE_NOMINAL { Text = "NOMINAL" ; };
+    String SC_OPCODE_SUB_TOTAL { Text = "SUBTOTAL" ; };
+    String SC_OPCODE_DB_SUM { Text = "DSUM" ; };
+    String SC_OPCODE_DB_COUNT { Text = "DCOUNT" ; };
+    String SC_OPCODE_DB_COUNT_2 { Text = "DCOUNTA" ; };
+    String SC_OPCODE_DB_AVERAGE { Text = "DAVERAGE" ; };
+    String SC_OPCODE_DB_GET { Text = "DGET" ; };
+    String SC_OPCODE_DB_MAX { Text = "DMAX" ; };
+    String SC_OPCODE_DB_MIN { Text = "DMIN" ; };
+    String SC_OPCODE_DB_PRODUCT { Text = "DPRODUCT" ; };
+    String SC_OPCODE_DB_STD_DEV { Text = "DSTDEV" ; };
+    String SC_OPCODE_DB_STD_DEV_P { Text = "DSTDEVP" ; };
+    String SC_OPCODE_DB_VAR { Text = "DVAR" ; };
+    String SC_OPCODE_DB_VAR_P { Text = "DVARP" ; };
+    String SC_OPCODE_INDIRECT { Text = "INDIRECT" ; };
+    String SC_OPCODE_ADDRESS { Text = "ADDRESS" ; };
+    String SC_OPCODE_MATCH { Text = "MATCH" ; };
+    String SC_OPCODE_COUNT_EMPTY_CELLS { Text = "COUNTBLANK" ; };
+    String SC_OPCODE_COUNT_IF { Text = "COUNTIF" ; };
+    String SC_OPCODE_SUM_IF { Text = "SUMIF" ; };
+    String SC_OPCODE_AVERAGE_IF { Text = "AVERAGEIF" ; };
+    String SC_OPCODE_SUM_IFS { Text = "SUMIFS" ; };
+    String SC_OPCODE_AVERAGE_IFS { Text = "AVERAGEIFS" ; };
+    String SC_OPCODE_COUNT_IFS { Text = "COUNTIFS" ; };
+    String SC_OPCODE_LOOKUP { Text = "LOOKUP" ; };
+    String SC_OPCODE_V_LOOKUP { Text = "VLOOKUP" ; };
+    String SC_OPCODE_H_LOOKUP { Text = "HLOOKUP" ; };
+    String SC_OPCODE_MULTI_AREA { Text = "MULTIRANGE" ; };      // legacy for range list (union)
+    String SC_OPCODE_OFFSET { Text = "OFFSET" ; };
+    String SC_OPCODE_INDEX { Text = "INDEX" ; };
+    String SC_OPCODE_AREAS { Text = "AREAS" ; };
+    String SC_OPCODE_CURRENCY { Text = "DOLLAR" ; };
+    String SC_OPCODE_REPLACE { Text = "REPLACE" ; };
+    String SC_OPCODE_FIXED { Text = "FIXED" ; };
+    String SC_OPCODE_FIND { Text = "FIND" ; };
+    String SC_OPCODE_EXACT { Text = "EXACT" ; };
+    String SC_OPCODE_LEFT { Text = "LEFT" ; };
+    String SC_OPCODE_RIGHT { Text = "RIGHT" ; };
+    String SC_OPCODE_SEARCH { Text = "SEARCH" ; };
+    String SC_OPCODE_MID { Text = "MID" ; };
+    String SC_OPCODE_LENB { Text = "LENB" ; };
+    String SC_OPCODE_RIGHTB { Text = "RIGHTB" ; };
+    String SC_OPCODE_LEFTB { Text = "LEFTB" ; };
+    String SC_OPCODE_MIDB { Text = "MIDB" ; };
+    String SC_OPCODE_TEXT { Text = "TEXT" ; };
+    String SC_OPCODE_SUBSTITUTE { Text = "SUBSTITUTE" ; };
+    String SC_OPCODE_REPT { Text = "REPT" ; };
+    String SC_OPCODE_CONCAT { Text = "CONCATENATE" ; };
+    String SC_OPCODE_MAT_VALUE { Text = "MVALUE" ; };
+    String SC_OPCODE_MAT_DET { Text = "MDETERM" ; };
+    String SC_OPCODE_MAT_INV { Text = "MINVERSE" ; };
+    String SC_OPCODE_MAT_MULT { Text = "MMULT" ; };
+    String SC_OPCODE_MAT_TRANS { Text = "TRANSPOSE" ; };
+    String SC_OPCODE_MATRIX_UNIT { Text = "MUNIT" ; };
+    String SC_OPCODE_BACK_SOLVER { Text = "GOALSEEK" ; };
+    String SC_OPCODE_HYP_GEOM_DIST { Text = "HYPGEOMDIST" ; };
+    String SC_OPCODE_LOG_NORM_DIST { Text = "LOGNORMDIST" ; };
+    String SC_OPCODE_T_DIST { Text = "TDIST" ; };
+    String SC_OPCODE_F_DIST { Text = "FDIST" ; };
+    String SC_OPCODE_CHI_DIST { Text = "CHIDIST" ; };
+    String SC_OPCODE_WEIBULL { Text = "WEIBULL" ; };
+    String SC_OPCODE_NEG_BINOM_VERT { Text = "NEGBINOMDIST" ; };
+    String SC_OPCODE_KRIT_BINOM { Text = "CRITBINOM" ; };
+    String SC_OPCODE_BINOM_INV { Text = "_xlfn.BINOM.INV" ; };
+    String SC_OPCODE_KURT { Text = "KURT" ; };
+    String SC_OPCODE_HAR_MEAN { Text = "HARMEAN" ; };
+    String SC_OPCODE_GEO_MEAN { Text = "GEOMEAN" ; };
+    String SC_OPCODE_STANDARD { Text = "STANDARDIZE" ; };
+    String SC_OPCODE_AVE_DEV { Text = "AVEDEV" ; };
+    String SC_OPCODE_SCHIEFE { Text = "SKEW" ; };
+    String SC_OPCODE_SKEWP   { Text = "SKEWP" ; };
+    String SC_OPCODE_DEV_SQ { Text = "DEVSQ" ; };
+    String SC_OPCODE_MEDIAN { Text = "MEDIAN" ; };
+    String SC_OPCODE_MODAL_VALUE { Text = "MODE" ; };
+    String SC_OPCODE_Z_TEST { Text = "ZTEST" ; };
+    String SC_OPCODE_T_TEST { Text = "TTEST" ; };
+    String SC_OPCODE_RANK { Text = "RANK" ; };
+    String SC_OPCODE_PERCENTILE { Text = "PERCENTILE" ; };
+    String SC_OPCODE_PERCENT_RANK { Text = "PERCENTRANK" ; };
+    String SC_OPCODE_LARGE { Text = "LARGE" ; };
+    String SC_OPCODE_SMALL { Text = "SMALL" ; };
+    String SC_OPCODE_FREQUENCY { Text = "FREQUENCY" ; };
+    String SC_OPCODE_QUARTILE { Text = "QUARTILE" ; };
+    String SC_OPCODE_NORM_INV { Text = "NORMINV" ; };
+    String SC_OPCODE_CONFIDENCE { Text = "CONFIDENCE" ; };
+    String SC_OPCODE_F_TEST { Text = "FTEST" ; };
+    String SC_OPCODE_TRIM_MEAN { Text = "TRIMMEAN" ; };
+    String SC_OPCODE_PROB { Text = "PROB" ; };
+    String SC_OPCODE_CORREL { Text = "CORREL" ; };
+    String SC_OPCODE_COVAR { Text = "COVAR" ; };
+    String SC_OPCODE_COVARIANCE_P { Text = "COVARIANCE.P" ; };
+    String SC_OPCODE_COVARIANCE_S { Text = "COVARIANCE.S" ; };
+    String SC_OPCODE_PEARSON { Text = "PEARSON" ; };
+    String SC_OPCODE_RSQ { Text = "RSQ" ; };
+    String SC_OPCODE_STEYX { Text = "STEYX" ; };
+    String SC_OPCODE_SLOPE { Text = "SLOPE" ; };
+    String SC_OPCODE_INTERCEPT { Text = "INTERCEPT" ; };
+    String SC_OPCODE_TREND { Text = "TREND" ; };
+    String SC_OPCODE_GROWTH { Text = "GROWTH" ; };
+    String SC_OPCODE_RGP { Text = "LINEST" ; };
+    String SC_OPCODE_RKP { Text = "LOGEST" ; };
+    String SC_OPCODE_FORECAST { Text = "FORECAST" ; };
+    String SC_OPCODE_CHI_INV { Text = "CHIINV" ; };
+    String SC_OPCODE_GAMMA_DIST { Text = "GAMMADIST" ; };
+    String SC_OPCODE_GAMMA_INV { Text = "GAMMAINV" ; };
+    String SC_OPCODE_T_INV { Text = "TINV" ; };
+    String SC_OPCODE_F_INV { Text = "FINV" ; };
+    String SC_OPCODE_CHI_TEST { Text = "CHITEST" ; };
+    String SC_OPCODE_CHI_TEST_MS { Text = "_xlfn.CHISQ.TEST" ; };
+    String SC_OPCODE_LOG_INV { Text = "LOGINV" ; };
+    String SC_OPCODE_TABLE_OP { Text = "TABLE" ; };
+    String SC_OPCODE_BETA_DIST { Text = "BETADIST" ; };
+    String SC_OPCODE_BETA_INV { Text = "BETAINV" ; };
+    String SC_OPCODE_BETA_DIST_MS { Text = "_xlfn.BETA.DIST" ; };
+    String SC_OPCODE_BETA_INV_MS { Text = "_xlfn.BETA.INV" ; };
+    String SC_OPCODE_WEEK { Text = "WEEKNUM" ; };
+    String SC_OPCODE_EASTERSUNDAY { Text = "EASTERSUNDAY" ; };
+    String SC_OPCODE_GET_DAY_OF_WEEK { Text = "WEEKDAY" ; };
+    String SC_OPCODE_NO_NAME { Text = "#NAME!" ; };
+    String SC_OPCODE_STYLE { Text = "STYLE" ; };
+    String SC_OPCODE_DDE { Text = "DDE" ; };
+    String SC_OPCODE_BASE { Text = "BASE" ; };
+    String SC_OPCODE_DECIMAL { Text = "DECIMAL" ; };
+    String SC_OPCODE_CONVERT { Text = "CONVERT" ; };
+    String SC_OPCODE_ROMAN { Text = "ROMAN" ; };
+    String SC_OPCODE_ARABIC { Text = "ARABIC" ; };
+    String SC_OPCODE_HYPERLINK { Text = "HYPERLINK" ; };
+    String SC_OPCODE_INFO { Text = "INFO" ; };
+    String SC_OPCODE_BAHTTEXT { Text = "BAHTTEXT" ; };
+    String SC_OPCODE_GET_PIVOT_DATA { Text = "GETPIVOTDATA" ; };
+    String SC_OPCODE_EUROCONVERT { Text = "EUROCONVERT" ; };
+    String SC_OPCODE_NUMBERVALUE { Text = "NUMBERVALUE" ; };
+    String SC_OPCODE_GAMMA { Text = "GAMMA" ; };
+    String SC_OPCODE_CHISQ_DIST { Text = "CHISQDIST" ; };
+    String SC_OPCODE_CHISQ_INV { Text = "CHISQINV" ;};
+    String SC_OPCODE_BITAND    { Text = "BITAND" ;};
+    String SC_OPCODE_BITOR    { Text = "BITOR" ;};
+    String SC_OPCODE_BITXOR    { Text = "BITXOR" ;};
+    String SC_OPCODE_BITRSHIFT    { Text = "BITRSHIFT" ;};
+    String SC_OPCODE_BITLSHIFT    { Text = "BITLSHIFT" ;};
+    /* BEGIN defined ERROR.TYPE() values. */
+    String SC_OPCODE_ERROR_NULL    { Text = "#NULL!"  ; };
+    String SC_OPCODE_ERROR_DIVZERO { Text = "#DIV/0!" ; };
+    String SC_OPCODE_ERROR_VALUE   { Text = "#VALUE!" ; };
+    String SC_OPCODE_ERROR_REF     { Text = "#REF!"   ; };
+    String SC_OPCODE_ERROR_NAME    { Text = "#NAME?"  ; };
+    String SC_OPCODE_ERROR_NUM     { Text = "#NUM!"   ; };
+    String SC_OPCODE_ERROR_NA      { Text = "#N/A"    ; };
+    /* END defined ERROR.TYPE() values. */
+    String SC_OPCODE_FILTERXML     { Text = "FILTERXML";};
+    String SC_OPCODE_WEBSERVICE    { Text = "WEBSERVICE"; };
+};
+
 // DO NOT CHANGE NAMES! Only add functions.
 // These English names are used internally to store/load ODF v1.0/v1.1 and for
 // API XFunctionAccess.
commit cff128c683d56078af5f1077f332477647c975c1
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Nov 8 14:49:44 2013 -0500

    Group formula cells if we can, to avoid cloning of token array instances.
    
    Change-Id: I584e6d0c34f972c1ae5105a80d201f32dd8590d9

diff --git a/sc/source/filter/oox/formulabuffer.cxx b/sc/source/filter/oox/formulabuffer.cxx
index eb1892b..4bdb6ae 100644
--- a/sc/source/filter/oox/formulabuffer.cxx
+++ b/sc/source/filter/oox/formulabuffer.cxx
@@ -189,7 +189,24 @@ void applyCellFormulas(
         if (p)
         {
             // Use the cached version to avoid re-compilation.
-            ScFormulaCell* pCell = new ScFormulaCell(&rDoc.getDoc(), aPos, p->mpCell->GetCode()->Clone());
+
+            ScFormulaCell* pCell = NULL;
+            if (p->mnRow + 1 == aPos.Row())
+            {
+                // Put them in the same formula group.
+                ScFormulaCell& rPrev = *p->mpCell;
+                ScFormulaCellGroupRef xGroup = rPrev.GetCellGroup();
+                if (!xGroup)
+                    // Last cell is not grouped yet. Start a new group.
+                    xGroup = rPrev.CreateCellGroup(p->mnRow, 1, false);
+
+                ++xGroup->mnLength;
+
+                pCell = new ScFormulaCell(&rDoc.getDoc(), aPos, xGroup);
+            }
+            else
+                pCell = new ScFormulaCell(&rDoc.getDoc(), aPos, p->mpCell->GetCode()->Clone());
+
             rDoc.setFormulaCell(aPos, pCell);
 
             // Update the cache.
commit b21cf4c67bb5ebe976432660d97388d754f9cbbe
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Nov 8 14:36:40 2013 -0500

    This is clearly a mistake.
    
    Change-Id: Id87e120d80b823db9be989db7a7b2ac383304f77

diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 12fc80a..0b7f0c3 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -1284,7 +1284,7 @@ class CopyToClipHandler
         for (++it; it != itEnd; ++it, pPrev = pCur)
         {
             pCur = *it;
-            ScFormulaCell::CompareState eState = pPrev->CompareByTokenArray(*pPrev);
+            ScFormulaCell::CompareState eState = pPrev->CompareByTokenArray(*pCur);
             if (eState == ScFormulaCell::NotEqual)
                 continue;
 
commit 45709a91db0cc90c66916a3db2d7c148f25a8ba0
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Nov 8 14:30:03 2013 -0500

    Store the formula cell instance in cache rather than the token array.
    
    Change-Id: I1c4a0897c46458d6ee086e7f72ab8a03aa54c9e0

diff --git a/sc/source/filter/oox/formulabuffer.cxx b/sc/source/filter/oox/formulabuffer.cxx
index d9c164a..eb1892b 100644
--- a/sc/source/filter/oox/formulabuffer.cxx
+++ b/sc/source/filter/oox/formulabuffer.cxx
@@ -51,10 +51,11 @@ public:
     struct Item : boost::noncopyable
     {
         SCROW mnRow;
-        boost::scoped_ptr<ScTokenArray> mpCode;
+        ScFormulaCell* mpCell;
 
-        Item() : mnRow(-1), mpCode(NULL) {}
-        Item( SCROW nRow, ScTokenArray* p ) : mnRow(nRow), mpCode(p) {}
+        Item() : mnRow(-1), mpCell(NULL) {}
+        Item( SCROW nRow, ScFormulaCell* pCell ) :
+            mnRow(nRow), mpCell(pCell) {}
     };
 
     CachedTokenArray( ScDocument& rDoc ) : mrDoc(rDoc) {}
@@ -74,7 +75,7 @@ public:
             return NULL;
 
         Item& rCached = *it->second;
-        ScCompiler aComp(&mrDoc, rPos, *rCached.mpCode);
+        ScCompiler aComp(&mrDoc, rPos, *rCached.mpCell->GetCode());
         aComp.SetGrammar(formula::FormulaGrammar::GRAM_ENGLISH_XL_OOX);
         OUStringBuffer aBuf;
         aComp.CreateStringFromTokenArray(aBuf);
@@ -85,7 +86,7 @@ public:
         return NULL;
     }
 
-    void store( const ScAddress& rPos, const ScTokenArray& rArray )
+    void store( const ScAddress& rPos, ScFormulaCell* pCell )
     {
         ColCacheType::iterator it = maCache.find(rPos.Col());
         if (it == maCache.end())
@@ -100,8 +101,9 @@ public:
             it = r.first;
         }
 
-        it->second->mnRow = rPos.Row();
-        it->second->mpCode.reset(rArray.Clone());
+        Item& rItem = *it->second;
+        rItem.mnRow = rPos.Row();
+        rItem.mpCell = pCell;
     }
 
 private:
@@ -187,8 +189,12 @@ void applyCellFormulas(
         if (p)
         {
             // Use the cached version to avoid re-compilation.
-            ScFormulaCell* pCell = new ScFormulaCell(&rDoc.getDoc(), aPos, p->mpCode->Clone());
+            ScFormulaCell* pCell = new ScFormulaCell(&rDoc.getDoc(), aPos, p->mpCell->GetCode()->Clone());
             rDoc.setFormulaCell(aPos, pCell);
+
+            // Update the cache.
+            p->mnRow = aPos.Row();
+            p->mpCell = pCell;
             continue;
         }
 
@@ -201,7 +207,7 @@ void applyCellFormulas(
 
         ScFormulaCell* pCell = new ScFormulaCell(&rDoc.getDoc(), aPos, pCode);
         rDoc.setFormulaCell(aPos, pCell);
-        rCache.store(aPos, *pCode);
+        rCache.store(aPos, pCell);
     }
 }
 
commit efd1fc1296b38f0db5ad44ab680fa804f8609766
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Nov 8 14:19:19 2013 -0500

    Create formula cells there...
    
    Change-Id: Idfd4081245905cdc88ad0da195b81be7e34ebf21

diff --git a/sc/source/filter/oox/formulabuffer.cxx b/sc/source/filter/oox/formulabuffer.cxx
index 86c9e6c..d9c164a 100644
--- a/sc/source/filter/oox/formulabuffer.cxx
+++ b/sc/source/filter/oox/formulabuffer.cxx
@@ -46,6 +46,8 @@ namespace {
  */
 class CachedTokenArray : boost::noncopyable
 {
+public:
+
     struct Item : boost::noncopyable
     {
         SCROW mnRow;
@@ -55,11 +57,6 @@ class CachedTokenArray : boost::noncopyable
         Item( SCROW nRow, ScTokenArray* p ) : mnRow(nRow), mpCode(p) {}
     };
 
-    typedef boost::unordered_map<SCCOL, Item*> ColCacheType;
-    ColCacheType maCache;
-    ScDocument& mrDoc;
-
-public:
     CachedTokenArray( ScDocument& rDoc ) : mrDoc(rDoc) {}
 
     ~CachedTokenArray()
@@ -69,21 +66,21 @@ public:
             delete it->second;
     }
 
-    const ScTokenArray* get( const ScAddress& rPos, const OUString& rFormula ) const
+    Item* get( const ScAddress& rPos, const OUString& rFormula )
     {
         // Check if a token array is cached for this column.
-        ColCacheType::const_iterator it = maCache.find(rPos.Col());
+        ColCacheType::iterator it = maCache.find(rPos.Col());
         if (it == maCache.end())
             return NULL;
 
-        const Item& rCached = *it->second;
+        Item& rCached = *it->second;
         ScCompiler aComp(&mrDoc, rPos, *rCached.mpCode);
         aComp.SetGrammar(formula::FormulaGrammar::GRAM_ENGLISH_XL_OOX);
         OUStringBuffer aBuf;
         aComp.CreateStringFromTokenArray(aBuf);
         OUString aPredicted = aBuf.makeStringAndClear();
         if (rFormula == aPredicted)
-            return rCached.mpCode.get();
+            return &rCached;
 
         return NULL;
     }
@@ -106,6 +103,11 @@ public:
         it->second->mnRow = rPos.Row();
         it->second->mpCode.reset(rArray.Clone());
     }
+
+private:
+    typedef boost::unordered_map<SCCOL, Item*> ColCacheType;
+    ColCacheType maCache;
+    ScDocument& mrDoc;
 };
 
 void applySharedFormulas(
@@ -181,11 +183,12 @@ void applyCellFormulas(
     {
         ScAddress aPos;
         ScUnoConversion::FillScAddress(aPos, it->maCellAddress);
-        const ScTokenArray* p = rCache.get(aPos, it->maTokenStr);
+        CachedTokenArray::Item* p = rCache.get(aPos, it->maTokenStr);
         if (p)
         {
             // Use the cached version to avoid re-compilation.
-            rDoc.setFormulaCell(aPos, p->Clone());
+            ScFormulaCell* pCell = new ScFormulaCell(&rDoc.getDoc(), aPos, p->mpCode->Clone());
+            rDoc.setFormulaCell(aPos, pCell);
             continue;
         }
 
@@ -196,7 +199,8 @@ void applyCellFormulas(
         if (!pCode)
             continue;
 
-        rDoc.setFormulaCell(aPos, pCode);
+        ScFormulaCell* pCell = new ScFormulaCell(&rDoc.getDoc(), aPos, pCode);
+        rDoc.setFormulaCell(aPos, pCell);
         rCache.store(aPos, *pCode);
     }
 }
commit 077716190f87118a1572e243f59bd96933042d9b
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Nov 8 12:33:57 2013 -0500

    Cache previous formula tokens to avoid formula re-compilations.
    
    Change-Id: If20e0ebf5410af0b7655f36f7e4fc06f53d8b14b

diff --git a/sc/source/filter/oox/formulabuffer.cxx b/sc/source/filter/oox/formulabuffer.cxx
index fa8e06a..86c9e6c 100644
--- a/sc/source/filter/oox/formulabuffer.cxx
+++ b/sc/source/filter/oox/formulabuffer.cxx
@@ -34,11 +34,80 @@ using namespace ::com::sun::star::sheet;
 using namespace ::com::sun::star::container;
 
 #include <boost/scoped_ptr.hpp>
+#include <boost/noncopyable.hpp>
 
 namespace oox { namespace xls {
 
 namespace {
 
+/**
+ * Cache the token array for the last cell position in each column. We use
+ * one cache per sheet.
+ */
+class CachedTokenArray : boost::noncopyable
+{
+    struct Item : boost::noncopyable
+    {
+        SCROW mnRow;
+        boost::scoped_ptr<ScTokenArray> mpCode;
+
+        Item() : mnRow(-1), mpCode(NULL) {}
+        Item( SCROW nRow, ScTokenArray* p ) : mnRow(nRow), mpCode(p) {}
+    };
+
+    typedef boost::unordered_map<SCCOL, Item*> ColCacheType;
+    ColCacheType maCache;
+    ScDocument& mrDoc;
+
+public:
+    CachedTokenArray( ScDocument& rDoc ) : mrDoc(rDoc) {}
+
+    ~CachedTokenArray()
+    {
+        ColCacheType::const_iterator it = maCache.begin(), itEnd = maCache.end();
+        for (; it != itEnd; ++it)
+            delete it->second;
+    }
+
+    const ScTokenArray* get( const ScAddress& rPos, const OUString& rFormula ) const
+    {
+        // Check if a token array is cached for this column.
+        ColCacheType::const_iterator it = maCache.find(rPos.Col());
+        if (it == maCache.end())
+            return NULL;
+
+        const Item& rCached = *it->second;
+        ScCompiler aComp(&mrDoc, rPos, *rCached.mpCode);
+        aComp.SetGrammar(formula::FormulaGrammar::GRAM_ENGLISH_XL_OOX);
+        OUStringBuffer aBuf;
+        aComp.CreateStringFromTokenArray(aBuf);
+        OUString aPredicted = aBuf.makeStringAndClear();
+        if (rFormula == aPredicted)
+            return rCached.mpCode.get();
+
+        return NULL;
+    }
+
+    void store( const ScAddress& rPos, const ScTokenArray& rArray )
+    {
+        ColCacheType::iterator it = maCache.find(rPos.Col());
+        if (it == maCache.end())
+        {
+            // Create an entry for this column.
+            std::pair<ColCacheType::iterator,bool> r =
+                maCache.insert(ColCacheType::value_type(rPos.Col(), new Item));
+            if (!r.second)
+                // Insertion failed.
+                return;
+
+            it = r.first;
+        }
+
+        it->second->mnRow = rPos.Row();
+        it->second->mpCode.reset(rArray.Clone());
+    }
+};
+
 void applySharedFormulas(
     ScDocumentImport& rDoc,
     SvNumberFormatter& rFormatter,
@@ -104,7 +173,7 @@ void applySharedFormulas(
 }
 
 void applyCellFormulas(
-    ScDocumentImport& rDoc, SvNumberFormatter& rFormatter,
+    ScDocumentImport& rDoc, CachedTokenArray& rCache, SvNumberFormatter& rFormatter,
     const std::vector<FormulaBuffer::TokenAddressItem>& rCells )
 {
     std::vector<FormulaBuffer::TokenAddressItem>::const_iterator it = rCells.begin(), itEnd = rCells.end();
@@ -112,6 +181,14 @@ void applyCellFormulas(
     {
         ScAddress aPos;
         ScUnoConversion::FillScAddress(aPos, it->maCellAddress);
+        const ScTokenArray* p = rCache.get(aPos, it->maTokenStr);
+        if (p)
+        {
+            // Use the cached version to avoid re-compilation.
+            rDoc.setFormulaCell(aPos, p->Clone());
+            continue;
+        }
+
         ScCompiler aCompiler(&rDoc.getDoc(), aPos);
         aCompiler.SetNumberFormatter(&rFormatter);
         aCompiler.SetGrammar(formula::FormulaGrammar::GRAM_ENGLISH_XL_OOX);
@@ -120,6 +197,7 @@ void applyCellFormulas(
             continue;
 
         rDoc.setFormulaCell(aPos, pCode);
+        rCache.store(aPos, *pCode);
     }
 }
 
@@ -185,7 +263,10 @@ protected:
             applySharedFormulas(mrDoc, *mpFormatter, *mrItem.mpSharedFormulaEntries, *mrItem.mpSharedFormulaIDs);
 
         if (mrItem.mpCellFormulas)
-            applyCellFormulas(mrDoc, *mpFormatter, *mrItem.mpCellFormulas);
+        {
+            CachedTokenArray aCache(mrDoc.getDoc());
+            applyCellFormulas(mrDoc, aCache, *mpFormatter, *mrItem.mpCellFormulas);
+        }
 
         if (mrItem.mpArrayFormulas)
             applyArrayFormulas(mrDoc, *mpFormatter, *mrItem.mpArrayFormulas);
commit 26c087e4280c66210b71eee6e42770cd44087f27
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Nov 8 10:26:47 2013 -0500

    Remove mutexes from external ref manager.
    
    Change-Id: I4857bb3a1804d4cd53c3e25a7586bd68ab95a202

diff --git a/sc/inc/externalrefmgr.hxx b/sc/inc/externalrefmgr.hxx
index e7a5e79..c072cfd 100644
--- a/sc/inc/externalrefmgr.hxx
+++ b/sc/inc/externalrefmgr.hxx
@@ -768,12 +768,6 @@ private:
 private:
     ScDocument* mpDoc;
 
-    /** Mutex for accessing cached data and/or source document shells. */
-    mutable osl::Mutex maMtxCacheAccess;
-
-    /** Mutex for source document meta-data access. */
-    mutable osl::Mutex maMtxSrcFiles;
-
     /** cache of referenced ranges and names from source documents. */
     ScExternalRefCache maRefCache;
 
diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx
index 9c07fd7..c06490e 100644
--- a/sc/source/ui/docshell/externalrefmgr.cxx
+++ b/sc/source/ui/docshell/externalrefmgr.cxx
@@ -1606,7 +1606,6 @@ void ScExternalRefManager::getAllCachedNumberFormats(vector<sal_uInt32>& rNumFmt
 
 sal_uInt16 ScExternalRefManager::getExternalFileCount() const
 {
-    osl::MutexGuard aGuard(&maMtxSrcFiles);
     return static_cast< sal_uInt16 >( maSrcFiles.size() );
 }
 
@@ -1759,8 +1758,6 @@ ScExternalRefCache::TokenRef ScExternalRefManager::getSingleRefToken(
     sal_uInt16 nFileId, const OUString& rTabName, const ScAddress& rCell,
     const ScAddress* pCurPos, SCTAB* pTab, ScExternalRefCache::CellFormat* pFmt)
 {
-    osl::MutexGuard aGuard(&maMtxCacheAccess);
-
     if (pCurPos)
         insertRefCell(nFileId, *pCurPos);
 
@@ -1853,8 +1850,6 @@ ScExternalRefCache::TokenRef ScExternalRefManager::getSingleRefToken(
 ScExternalRefCache::TokenArrayRef ScExternalRefManager::getDoubleRefTokens(
     sal_uInt16 nFileId, const OUString& rTabName, const ScRange& rRange, const ScAddress* pCurPos)
 {
-    osl::MutexGuard aGuard(&maMtxCacheAccess);
-
     if (pCurPos)
         insertRefCell(nFileId, *pCurPos);
 
@@ -1901,8 +1896,6 @@ ScExternalRefCache::TokenArrayRef ScExternalRefManager::getDoubleRefTokens(
 ScExternalRefCache::TokenArrayRef ScExternalRefManager::getRangeNameTokens(
     sal_uInt16 nFileId, const OUString& rName, const ScAddress* pCurPos)
 {
-    osl::MutexGuard aGuard(&maMtxCacheAccess);
-
     if (pCurPos)
         insertRefCell(nFileId, *pCurPos);
 
@@ -1956,8 +1949,6 @@ bool hasRangeName(ScDocument& rDoc, const OUString& rName)
 
 bool ScExternalRefManager::isValidRangeName(sal_uInt16 nFileId, const OUString& rName)
 {
-    osl::MutexGuard aGuard(&maMtxCacheAccess);
-
     maybeLinkExternalFile(nFileId);
     ScDocument* pSrcDoc = getInMemorySrcDocument(nFileId);
     if (pSrcDoc)
@@ -2415,7 +2406,6 @@ void ScExternalRefManager::SrcFileData::maybeCreateRealFileName(const OUString&
 
 void ScExternalRefManager::maybeCreateRealFileName(sal_uInt16 nFileId)
 {
-    osl::MutexGuard aGuard(&maMtxSrcFiles);
     if (nFileId >= maSrcFiles.size())
         return;
 
@@ -2460,8 +2450,6 @@ void ScExternalRefManager::convertToAbsName(OUString& rFile) const
 
 sal_uInt16 ScExternalRefManager::getExternalFileId(const OUString& rFile)
 {
-    osl::MutexGuard aGuard(&maMtxSrcFiles);
-
     vector<SrcFileData>::const_iterator itrBeg = maSrcFiles.begin(), itrEnd = maSrcFiles.end();
     vector<SrcFileData>::const_iterator itr = find_if(itrBeg, itrEnd, FindSrcFileByName(rFile));
     if (itr != itrEnd)
@@ -2478,8 +2466,6 @@ sal_uInt16 ScExternalRefManager::getExternalFileId(const OUString& rFile)
 
 const OUString* ScExternalRefManager::getExternalFileName(sal_uInt16 nFileId, bool bForceOriginal)
 {
-    osl::MutexGuard aGuard(&maMtxSrcFiles);
-
     if (nFileId >= maSrcFiles.size())
         return NULL;
 
@@ -2496,14 +2482,11 @@ const OUString* ScExternalRefManager::getExternalFileName(sal_uInt16 nFileId, bo
 
 bool ScExternalRefManager::hasExternalFile(sal_uInt16 nFileId) const
 {
-    osl::MutexGuard aGuard(&maMtxSrcFiles);
     return nFileId < maSrcFiles.size();
 }
 
 bool ScExternalRefManager::hasExternalFile(const OUString& rFile) const
 {
-    osl::MutexGuard aGuard(&maMtxSrcFiles);
-
     vector<SrcFileData>::const_iterator itrBeg = maSrcFiles.begin(), itrEnd = maSrcFiles.end();
     vector<SrcFileData>::const_iterator itr = find_if(itrBeg, itrEnd, FindSrcFileByName(rFile));
     return itr != itrEnd;
@@ -2602,8 +2585,6 @@ void ScExternalRefManager::breakLink(sal_uInt16 nFileId)
 
 void ScExternalRefManager::switchSrcFile(sal_uInt16 nFileId, const OUString& rNewFile, const OUString& rNewFilter)
 {
-    osl::MutexGuard aGuard(&maMtxSrcFiles);
-
     maSrcFiles[nFileId].maFileName = rNewFile;
     maSrcFiles[nFileId].maRelativeName = OUString();
     maSrcFiles[nFileId].maRealFileName = OUString();
@@ -2618,8 +2599,6 @@ void ScExternalRefManager::switchSrcFile(sal_uInt16 nFileId, const OUString& rNe
 
 void ScExternalRefManager::setRelativeFileName(sal_uInt16 nFileId, const OUString& rRelUrl)
 {
-    osl::MutexGuard aGuard(&maMtxSrcFiles);
-
     if (nFileId >= maSrcFiles.size())
         return;
     maSrcFiles[nFileId].maRelativeName = rRelUrl;
@@ -2627,8 +2606,6 @@ void ScExternalRefManager::setRelativeFileName(sal_uInt16 nFileId, const OUStrin
 
 void ScExternalRefManager::setFilterData(sal_uInt16 nFileId, const OUString& rFilterName, const OUString& rOptions)
 {
-    osl::MutexGuard aGuard(&maMtxSrcFiles);
-
     if (nFileId >= maSrcFiles.size())
         return;
     maSrcFiles[nFileId].maFilterName = rFilterName;
@@ -2647,13 +2624,11 @@ void ScExternalRefManager::clear()
 
 bool ScExternalRefManager::hasExternalData() const
 {
-    osl::MutexGuard aGuard(&maMtxSrcFiles);
     return !maSrcFiles.empty();
 }
 
 void ScExternalRefManager::resetSrcFileData(const OUString& rBaseFileUrl)
 {
-    osl::MutexGuard aGuard(&maMtxSrcFiles);
     for (vector<SrcFileData>::iterator itr = maSrcFiles.begin(), itrEnd = maSrcFiles.end();
           itr != itrEnd; ++itr)
     {
@@ -2669,7 +2644,6 @@ void ScExternalRefManager::resetSrcFileData(const OUString& rBaseFileUrl)
 
 void ScExternalRefManager::updateAbsAfterLoad()
 {
-    osl::MutexGuard aGuard(&maMtxSrcFiles);
     OUString aOwn( getOwnDocumentName() );
     for (vector<SrcFileData>::iterator itr = maSrcFiles.begin(), itrEnd = maSrcFiles.end();
           itr != itrEnd; ++itr)
commit 7498399a27488761b795c7c5f1a2638c3fb3855e
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Nov 8 10:06:51 2013 -0500

    Revert "Guard access to external ref manager instance."
    
    This reverts commit 7cf9ea71ad1364d00eaca95b309cc6c0f35cf6cb.

diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 08ba3a2..09f1466 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -39,7 +39,6 @@
 #include "calcmacros.hxx"
 #include <tools/fract.hxx>
 #include <tools/gen.hxx>
-#include "osl/mutex.hxx"
 
 #include <memory>
 #include <map>
@@ -299,9 +298,7 @@ private:
     ::std::auto_ptr<ScDocProtection> pDocProtection;
     ::std::auto_ptr<ScClipParam>     mpClipParam;
 
-    boost::scoped_ptr<ScExternalRefManager> mpExternalRefMgr;
-    mutable osl::Mutex maMtxExternalRefMgr;
-
+    ::std::auto_ptr<ScExternalRefManager> pExternalRefMgr;
     ::std::auto_ptr<ScMacroManager> mpMacroMgr;
 
 
@@ -664,7 +661,7 @@ public:
                                     const OUString& aFileName,
                                     const OUString& aTabName );
 
-    SC_DLLPUBLIC bool HasExternalRefManager() const;
+    bool            HasExternalRefManager() const { return pExternalRefMgr.get(); }
     SC_DLLPUBLIC ScExternalRefManager* GetExternalRefManager() const;
     bool            IsInExternalReferenceMarking() const;
     void            MarkUsedExternalReferences();
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index 846b5c8..23a4bcf 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -150,7 +150,7 @@ ScDocument::ScDocument( ScDocumentMode eMode, SfxObjectShell* pDocShell ) :
         pCacheFieldEditEngine( NULL ),
         pDocProtection( NULL ),
         mpClipParam( NULL),
-        mpExternalRefMgr( NULL ),
+        pExternalRefMgr( NULL ),
         mpMacroMgr( NULL ),
         pViewOptions( NULL ),
         pDocOptions( NULL ),
@@ -384,7 +384,7 @@ ScDocument::~ScDocument()
     mxFormulaParserPool.reset();
     // Destroy the external ref mgr instance here because it has a timer
     // which needs to be stopped before the app closes.
-    mpExternalRefMgr.reset();
+    pExternalRefMgr.reset();
 
     ScAddInAsync::RemoveDocument( this );
     ScAddInListener::RemoveDocument( this );
diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx
index 67fda15..73f8d71 100644
--- a/sc/source/core/data/documen3.cxx
+++ b/sc/source/core/data/documen3.cxx
@@ -582,41 +582,30 @@ bool ScDocument::LinkExternalTab( SCTAB& rTab, const OUString& aDocTab,
     return true;
 }
 
-bool ScDocument::HasExternalRefManager() const
-{
-    osl::MutexGuard aGuard(&maMtxExternalRefMgr);
-    return mpExternalRefMgr.get();
-}
-
 ScExternalRefManager* ScDocument::GetExternalRefManager() const
 {
-    osl::MutexGuard aGuard(&maMtxExternalRefMgr);
-
     ScDocument* pThis = const_cast<ScDocument*>(this);
-    if (!mpExternalRefMgr.get())
-        pThis->mpExternalRefMgr.reset( new ScExternalRefManager( pThis));
+    if (!pExternalRefMgr.get())
+        pThis->pExternalRefMgr.reset( new ScExternalRefManager( pThis));
 
-    return mpExternalRefMgr.get();
+    return pExternalRefMgr.get();
 }
 
 bool ScDocument::IsInExternalReferenceMarking() const
 {
-    osl::MutexGuard aGuard(&maMtxExternalRefMgr);
-    return mpExternalRefMgr.get() && mpExternalRefMgr->isInReferenceMarking();
+    return pExternalRefMgr.get() && pExternalRefMgr->isInReferenceMarking();
 }
 
 void ScDocument::MarkUsedExternalReferences()
 {
-    osl::MutexGuard aGuard(&maMtxExternalRefMgr);
-
-    if (!mpExternalRefMgr.get())
+    if (!pExternalRefMgr.get())
         return;
-    if (!mpExternalRefMgr->hasExternalData())
+    if (!pExternalRefMgr->hasExternalData())
         return;
     // Charts.
-    mpExternalRefMgr->markUsedByLinkListeners();
+    pExternalRefMgr->markUsedByLinkListeners();
     // Formula cells.
-    mpExternalRefMgr->markUsedExternalRefCells();
+    pExternalRefMgr->markUsedExternalRefCells();
 
     /* NOTE: Conditional formats and validation objects are marked when
      * collecting them during export. */
commit c35c28c785b9016e1504c3cffe4ec2f76736bc17
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Nov 8 09:51:23 2013 -0500

    We don't need to put this in a separate thread.
    
    We can do this on the main thread.
    
    Change-Id: I58a32d9e0ce2599c5822903393a5b698233599df

diff --git a/sc/source/filter/inc/formulabuffer.hxx b/sc/source/filter/inc/formulabuffer.hxx
index 7e881ee..2411466 100644
--- a/sc/source/filter/inc/formulabuffer.hxx
+++ b/sc/source/filter/inc/formulabuffer.hxx
@@ -31,20 +31,6 @@ namespace oox { namespace xls {
 
 class FormulaBuffer : public WorkbookHelper
 {
-    class FinalizeThread : public salhelper::Thread
-    {
-        FormulaBuffer& mrParent;
-        size_t mnThreadCount;
-    public:
-        FinalizeThread( FormulaBuffer& rParent, size_t nThreadCount );
-        virtual ~FinalizeThread();
-
-    protected:
-        virtual void execute();
-    };
-
-    friend class FinalizeThread;
-
 public:
     /**
      * Represents a shared formula definition.
diff --git a/sc/source/filter/oox/formulabuffer.cxx b/sc/source/filter/oox/formulabuffer.cxx
index f58e9f7..fa8e06a 100644
--- a/sc/source/filter/oox/formulabuffer.cxx
+++ b/sc/source/filter/oox/formulabuffer.cxx
@@ -214,15 +214,16 @@ FormulaBuffer::SheetItem::SheetItem() :
     mpSharedFormulaEntries(NULL),
     mpSharedFormulaIDs(NULL) {}
 
-FormulaBuffer::FinalizeThread::FinalizeThread( FormulaBuffer& rParent, size_t nThreadCount ) :
-    salhelper::Thread("xlsx-import-formula-buffer-finalize-thread"),
-    mrParent(rParent), mnThreadCount(nThreadCount) {}
-
-FormulaBuffer::FinalizeThread::~FinalizeThread() {}
+FormulaBuffer::FormulaBuffer( const WorkbookHelper& rHelper ) : WorkbookHelper( rHelper )
+{
+}
 
-void FormulaBuffer::FinalizeThread::execute()
+void FormulaBuffer::finalizeImport()
 {
-    ScDocumentImport& rDoc = mrParent.getDocImport();
+    ISegmentProgressBarRef xFormulaBar = getProgressBar().createSegment( getProgressBar().getFreeLength() );
+
+    const size_t nThreadCount = 1;
+    ScDocumentImport& rDoc = getDocImport();
     rDoc.getDoc().SetAutoNameCache(new ScAutoNameCache(&rDoc.getDoc()));
     ScExternalRefManager::ApiGuard aExtRefGuard(&rDoc.getDoc());
 
@@ -232,11 +233,11 @@ void FormulaBuffer::FinalizeThread::execute()
     std::vector<SheetItem> aSheetItems;
     aSheetItems.reserve(nTabCount);
     for (SCTAB nTab = 0; nTab < nTabCount; ++nTab)
-        aSheetItems.push_back(mrParent.getSheetItem(nTab));
+        aSheetItems.push_back(getSheetItem(nTab));
 
     typedef rtl::Reference<WorkerThread> WorkerThreadRef;
     std::vector<WorkerThreadRef> aThreads;
-    aThreads.reserve(mnThreadCount);
+    aThreads.reserve(nThreadCount);
 
     std::vector<SheetItem>::iterator it = aSheetItems.begin(), itEnd = aSheetItems.end();
 
@@ -246,7 +247,7 @@ void FormulaBuffer::FinalizeThread::execute()
     // lack.
     while (it != itEnd)
     {
-        for (size_t i = 0; i < mnThreadCount; ++i)
+        for (size_t i = 0; i < nThreadCount; ++i)
         {
             if (it == itEnd)
                 break;
@@ -267,21 +268,6 @@ void FormulaBuffer::FinalizeThread::execute()
     }
 
     rDoc.getDoc().SetAutoNameCache(NULL);
-}
-
-FormulaBuffer::FormulaBuffer( const WorkbookHelper& rHelper ) : WorkbookHelper( rHelper )
-{
-}
-
-void FormulaBuffer::finalizeImport()
-{
-    ISegmentProgressBarRef xFormulaBar = getProgressBar().createSegment( getProgressBar().getFreeLength() );
-
-    rtl::Reference<FinalizeThread> xThreadMgr(new FinalizeThread(*this, 1));
-    xThreadMgr->launch();
-
-    if (xThreadMgr.is())
-        xThreadMgr->join();
 
     xFormulaBar->setPosition( 1.0 );
 }
commit 6f1bcf5b9757ccbbcb9c858eaaf7f0e10f0de00a
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Nov 8 09:40:25 2013 -0500

    Revert "Guard CharacterClassificationImpl with mutex."
    
    This reverts commit fc04b55f7f96a4f70f31c145dafd44c1d9276a41.

diff --git a/i18npool/inc/characterclassificationImpl.hxx b/i18npool/inc/characterclassificationImpl.hxx
index 24221d1..e220968 100644
--- a/i18npool/inc/characterclassificationImpl.hxx
+++ b/i18npool/inc/characterclassificationImpl.hxx
@@ -26,8 +26,6 @@
 #include <com/sun/star/lang/XServiceInfo.hpp>
 #include <com/sun/star/uno/XComponentContext.hpp>
 
-#include "osl/mutex.hxx"
-
 namespace com { namespace sun { namespace star { namespace i18n {
 
 class CharacterClassificationImpl : public cppu::WeakImplHelper2
@@ -95,19 +93,17 @@ private:
             aLocale.Variant == rLocale.Variant;
         };
     };
+    std::vector<lookupTableItem*> lookupTable;
+    lookupTableItem *cachedItem;
+
+    com::sun::star::uno::Reference < com::sun::star::uno::XComponentContext > m_xContext;
+    com::sun::star::uno::Reference < XCharacterClassification > xUCI;
 
     com::sun::star::uno::Reference < XCharacterClassification > SAL_CALL
     getLocaleSpecificCharacterClassification(const com::sun::star::lang::Locale& rLocale) throw(com::sun::star::uno::RuntimeException);
     sal_Bool SAL_CALL
     createLocaleSpecificCharacterClassification(const OUString& serviceName, const com::sun::star::lang::Locale& rLocale);
 
-private:
-    std::vector<lookupTableItem*> lookupTable;
-    lookupTableItem *cachedItem;
-
-    com::sun::star::uno::Reference < com::sun::star::uno::XComponentContext > m_xContext;
-    com::sun::star::uno::Reference < XCharacterClassification > xUCI;
-    osl::Mutex maMtx;
 };
 
 } } } }
diff --git a/i18npool/source/characterclassification/characterclassificationImpl.cxx b/i18npool/source/characterclassification/characterclassificationImpl.cxx
index edcf9db..d65b5a5 100644
--- a/i18npool/source/characterclassification/characterclassificationImpl.cxx
+++ b/i18npool/source/characterclassification/characterclassificationImpl.cxx
@@ -47,7 +47,6 @@ OUString SAL_CALL
 CharacterClassificationImpl::toUpper( const OUString& Text, sal_Int32 nPos,
         sal_Int32 nCount, const Locale& rLocale ) throw(RuntimeException)
 {
-    osl::MutexGuard aGuard(&maMtx);
     return getLocaleSpecificCharacterClassification(rLocale)->toUpper(Text, nPos, nCount, rLocale);
 }
 
@@ -55,7 +54,6 @@ OUString SAL_CALL
 CharacterClassificationImpl::toLower( const OUString& Text, sal_Int32 nPos,
         sal_Int32 nCount, const Locale& rLocale ) throw(RuntimeException)
 {
-    osl::MutexGuard aGuard(&maMtx);
     return getLocaleSpecificCharacterClassification(rLocale)->toLower(Text, nPos, nCount, rLocale);
 }
 
@@ -63,7 +61,6 @@ OUString SAL_CALL
 CharacterClassificationImpl::toTitle( const OUString& Text, sal_Int32 nPos,
         sal_Int32 nCount, const Locale& rLocale ) throw(RuntimeException)
 {
-    osl::MutexGuard aGuard(&maMtx);
     return getLocaleSpecificCharacterClassification(rLocale)->toTitle(Text, nPos, nCount, rLocale);
 }
 
@@ -71,7 +68,6 @@ sal_Int16 SAL_CALL
 CharacterClassificationImpl::getType( const OUString& Text, sal_Int32 nPos )
         throw(RuntimeException)
 {
-    osl::MutexGuard aGuard(&maMtx);
     if (xUCI.is())
         return xUCI->getType(Text, nPos);
     throw RuntimeException();
@@ -81,7 +77,6 @@ sal_Int16 SAL_CALL
 CharacterClassificationImpl::getCharacterDirection( const OUString& Text, sal_Int32 nPos )
         throw(RuntimeException)
 {
-    osl::MutexGuard aGuard(&maMtx);
     if (xUCI.is())
         return xUCI->getCharacterDirection(Text, nPos);
     throw RuntimeException();
@@ -91,7 +86,6 @@ sal_Int16 SAL_CALL
 CharacterClassificationImpl::getScript( const OUString& Text, sal_Int32 nPos )
         throw(RuntimeException)
 {
-    osl::MutexGuard aGuard(&maMtx);
     if (xUCI.is())
         return xUCI->getScript(Text, nPos);
     throw RuntimeException();
@@ -101,7 +95,6 @@ sal_Int32 SAL_CALL
 CharacterClassificationImpl::getCharacterType( const OUString& Text, sal_Int32 nPos,
         const Locale& rLocale ) throw(RuntimeException)
 {
-    osl::MutexGuard aGuard(&maMtx);
     return getLocaleSpecificCharacterClassification(rLocale)->getCharacterType(Text, nPos, rLocale);
 }
 
@@ -109,7 +102,6 @@ sal_Int32 SAL_CALL
 CharacterClassificationImpl::getStringType( const OUString& Text, sal_Int32 nPos,
         sal_Int32 nCount, const Locale& rLocale ) throw(RuntimeException)
 {
-    osl::MutexGuard aGuard(&maMtx);
     return getLocaleSpecificCharacterClassification(rLocale)->getStringType(Text, nPos, nCount, rLocale);
 }
 
@@ -119,7 +111,6 @@ ParseResult SAL_CALL CharacterClassificationImpl::parseAnyToken(
         sal_Int32 contCharTokenType, const OUString& userDefinedCharactersCont )
         throw(RuntimeException)
 {
-    osl::MutexGuard aGuard(&maMtx);
     return getLocaleSpecificCharacterClassification(rLocale)->parseAnyToken(Text, nPos, rLocale,
             startCharTokenType,userDefinedCharactersStart,
             contCharTokenType, userDefinedCharactersCont);
@@ -132,7 +123,6 @@ ParseResult SAL_CALL CharacterClassificationImpl::parsePredefinedToken(
         const OUString& userDefinedCharactersStart, sal_Int32 contCharTokenType,
         const OUString& userDefinedCharactersCont ) throw(RuntimeException)
 {
-    osl::MutexGuard aGuard(&maMtx);
     return getLocaleSpecificCharacterClassification(rLocale)->parsePredefinedToken(
             nTokenType, Text, nPos, rLocale, startCharTokenType, userDefinedCharactersStart,
             contCharTokenType, userDefinedCharactersCont);
commit a95e099d48ff6c62c5fdb6768b87a52df622c9bd
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Thu Nov 7 14:46:53 2013 -0500

    Mutex access to the global theIndexTable.
    
    Change-Id: I31e2cf3a479e385aa0fca4678a3a2c7fa6cc4b5f

diff --git a/svl/source/numbers/zforlist.cxx b/svl/source/numbers/zforlist.cxx
index 2117041..accc557 100644
--- a/svl/source/numbers/zforlist.cxx
+++ b/svl/source/numbers/zforlist.cxx
@@ -71,9 +71,16 @@ using namespace ::std;
  * (old currency) is recognized as a date (#53155#). */
 #define UNKNOWN_SUBSTITUTE      LANGUAGE_ENGLISH_US
 
-static bool bIndexTableInitialized = false;
-static sal_uInt32 theIndexTable[NF_INDEX_TABLE_ENTRIES];
+struct IndexTable
+{
+    bool mbInitialized;
+    sal_uInt32 maData[NF_INDEX_TABLE_ENTRIES];
+    osl::Mutex maMtx;
+
+    IndexTable() : mbInitialized(false) {}
+};
 
+static IndexTable theIndexTable;
 
 // ====================================================================
 
@@ -2001,11 +2008,13 @@ sal_uInt32 SvNumberFormatter::GetFormatSpecialInfo( const OUString& rFormatStrin
 
 inline sal_uInt32 SetIndexTable( NfIndexTableOffset nTabOff, sal_uInt32 nIndOff )
 {
-    if ( !bIndexTableInitialized )
+    osl::MutexGuard aGuard(&theIndexTable.maMtx);
+
+    if (!theIndexTable.mbInitialized)
     {
-        DBG_ASSERT( theIndexTable[nTabOff] == NUMBERFORMAT_ENTRY_NOT_FOUND,
+        DBG_ASSERT(theIndexTable.maData[nTabOff] == NUMBERFORMAT_ENTRY_NOT_FOUND,
             "SetIndexTable: theIndexTable[nTabOff] already occupied" );
-        theIndexTable[nTabOff] = nIndOff;
+        theIndexTable.maData[nTabOff] = nIndOff;
     }
     return nIndOff;
 }
@@ -2196,13 +2205,17 @@ void SvNumberFormatter::ImpGenerateFormats( sal_uInt32 CLOffset, bool bNoAdditio
 {
     using namespace ::com::sun::star;
 
-    if ( !bIndexTableInitialized )
     {
-        for ( sal_uInt16 j=0; j<NF_INDEX_TABLE_ENTRIES; j++ )
+        osl::MutexGuard aGuard(&theIndexTable.maMtx);
+        if (!theIndexTable.mbInitialized)
         {
-            theIndexTable[j] = NUMBERFORMAT_ENTRY_NOT_FOUND;
+            for ( sal_uInt16 j=0; j<NF_INDEX_TABLE_ENTRIES; j++ )
+            {
+                theIndexTable.maData[j] = NUMBERFORMAT_ENTRY_NOT_FOUND;
+            }
         }
     }
+
     bool bOldConvertMode = pFormatScanner->GetConvertMode();
     if (bOldConvertMode)
     {
@@ -2631,8 +2644,10 @@ void SvNumberFormatter::ImpGenerateFormats( sal_uInt32 CLOffset, bool bNoAdditio
                                 CLOffset + SetIndexTable( NF_DATE_WW, nNewExtended++ ),
                                 SV_NUMBERFORMATTER_VERSION_NF_DATE_WW );
 
-
-    bIndexTableInitialized = true;
+    {
+        osl::MutexGuard aGuard(&theIndexTable.maMtx);
+        theIndexTable.mbInitialized = true;
+    }
     SAL_WARN_IF( nNewExtended > ZF_STANDARD_NEWEXTENDEDMAX, "svl.numbers",
         "ImpGenerateFormats: overflow of nNewExtended standard formats" );
 
@@ -3092,17 +3107,24 @@ sal_uInt32 SvNumberFormatter::GetFormatForLanguageIfBuiltIn( sal_uInt32 nFormat,
 sal_uInt32 SvNumberFormatter::GetFormatIndex( NfIndexTableOffset nTabOff,
                                               LanguageType eLnge )
 {
-    if ( nTabOff >= NF_INDEX_TABLE_ENTRIES ||
-         theIndexTable[nTabOff] == NUMBERFORMAT_ENTRY_NOT_FOUND )
-    {
+    if (nTabOff >= NF_INDEX_TABLE_ENTRIES)
         return NUMBERFORMAT_ENTRY_NOT_FOUND;
-    }
-    if ( eLnge == LANGUAGE_DONTKNOW )
-    {
+
+    if (eLnge == LANGUAGE_DONTKNOW)
         eLnge = IniLnge;
+
+    {
+        osl::MutexGuard aGuard(&theIndexTable.maMtx);
+        if (theIndexTable.maData[nTabOff] == NUMBERFORMAT_ENTRY_NOT_FOUND)
+            return NUMBERFORMAT_ENTRY_NOT_FOUND;
     }
+
     sal_uInt32 nCLOffset = ImpGenerateCL(eLnge);    // create new standard formats if necessary
-    return nCLOffset + theIndexTable[nTabOff];
+
+    {
+        osl::MutexGuard aGuard(&theIndexTable.maMtx);
+        return nCLOffset + theIndexTable.maData[nTabOff];
+    }
 }
 
 
@@ -3113,11 +3135,13 @@ NfIndexTableOffset SvNumberFormatter::GetIndexTableOffset( sal_uInt32 nFormat )
     {
         return NF_INDEX_TABLE_ENTRIES;      // not a built-in format
     }
-    for ( sal_uInt16 j = 0; j < NF_INDEX_TABLE_ENTRIES; j++ )
+
     {
-        if ( theIndexTable[j] == nOffset )
+        osl::MutexGuard aGuard(&theIndexTable.maMtx);
+        for ( sal_uInt16 j = 0; j < NF_INDEX_TABLE_ENTRIES; j++ )
         {
-            return (NfIndexTableOffset) j;
+            if (theIndexTable.maData[j] == nOffset)
+                return (NfIndexTableOffset) j;
         }
     }
     return NF_INDEX_TABLE_ENTRIES;      // bad luck
commit 853169de0b73924cb36af04c0e6377190502d991
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Thu Nov 7 14:16:48 2013 -0500

    Thread-safe way to check for presence of references in formula tokens.
    
    Change-Id: I995668d1e183dc0dae4f354889bc13053e858723

diff --git a/formula/source/core/api/token.cxx b/formula/source/core/api/token.cxx
index 8f0cfa8..ae1655e 100644
--- a/formula/source/core/api/token.cxx
+++ b/formula/source/core/api/token.cxx
@@ -130,6 +130,22 @@ bool FormulaToken::IsExternalRef() const
     return bRet;
 }
 
+bool FormulaToken::IsRef() const
+{
+    switch (eType)
+    {
+        case svSingleRef:
+        case svDoubleRef:
+        case svExternalSingleRef:
+        case svExternalDoubleRef:
+            return true;
+        default:
+            ;
+    }
+
+    return false;
+}
+
 bool FormulaToken::operator==( const FormulaToken& rToken ) const
 {
     // don't compare reference count!
@@ -538,6 +554,17 @@ FormulaToken* FormulaTokenArray::PeekPrevNoSpaces()
         return NULL;
 }
 
+bool FormulaTokenArray::HasReferences() const
+{
+    for (sal_uInt16 i = 0; i < nLen; ++i)
+    {
+        if (pCode[i]->IsRef())
+            return true;
+    }
+
+    return false;
+}
+
 bool FormulaTokenArray::HasExternalRef() const
 {
     for ( sal_uInt16 j=0; j < nLen; j++ )
diff --git a/include/formula/token.hxx b/include/formula/token.hxx
index 73f773b..002cefb 100644
--- a/include/formula/token.hxx
+++ b/include/formula/token.hxx
@@ -106,7 +106,10 @@ public:
     inline  void                Delete()                { delete this; }
     inline  StackVar            GetType() const         { return eType; }
             bool                IsFunction() const; // pure functions, no operators
-            bool                IsExternalRef() const;
+
+    bool IsExternalRef() const;
+    bool IsRef() const;
+
             sal_uInt8           GetParamCount() const;
 
     inline void IncRef() const
diff --git a/include/formula/tokenarray.hxx b/include/formula/tokenarray.hxx
index ddd7d81..9f8fed0 100644
--- a/include/formula/tokenarray.hxx
+++ b/include/formula/tokenarray.hxx
@@ -116,6 +116,8 @@ public:
     FormulaToken* LastRPN() { nIndex = nRPN; return PrevRPN(); }
     FormulaToken* PrevRPN();
 
+    bool HasReferences() const;
+
     bool    HasExternalRef() const;
     bool    HasOpCode( OpCode ) const;
     bool    HasOpCodeRPN( OpCode ) const;
diff --git a/sc/source/core/tool/rangenam.cxx b/sc/source/core/tool/rangenam.cxx
index 6096ecf..c1e2865 100644
--- a/sc/source/core/tool/rangenam.cxx
+++ b/sc/source/core/tool/rangenam.cxx
@@ -518,8 +518,7 @@ sal_uInt16 ScRangeData::GetErrCode() const
 
 bool ScRangeData::HasReferences() const
 {
-    pCode->Reset();
-    return pCode->GetNextReference() != NULL;
+    return pCode->HasReferences();
 }
 
 sal_uInt32 ScRangeData::GetUnoType() const
commit 1c720b2295304b645c9e3024e63fb626ca581d2b
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Thu Nov 7 13:35:24 2013 -0500

    Guard CharacterClassificationImpl with mutex.
    
    They are accessed from multiple threads frequently.
    
    Change-Id: I3f9720ede076109efe0b7eaa4a05dd50f2e38102

diff --git a/i18npool/inc/characterclassificationImpl.hxx b/i18npool/inc/characterclassificationImpl.hxx
index e220968..24221d1 100644
--- a/i18npool/inc/characterclassificationImpl.hxx
+++ b/i18npool/inc/characterclassificationImpl.hxx
@@ -26,6 +26,8 @@
 #include <com/sun/star/lang/XServiceInfo.hpp>
 #include <com/sun/star/uno/XComponentContext.hpp>
 
+#include "osl/mutex.hxx"
+
 namespace com { namespace sun { namespace star { namespace i18n {
 
 class CharacterClassificationImpl : public cppu::WeakImplHelper2
@@ -93,17 +95,19 @@ private:
             aLocale.Variant == rLocale.Variant;
         };
     };
-    std::vector<lookupTableItem*> lookupTable;
-    lookupTableItem *cachedItem;
-
-    com::sun::star::uno::Reference < com::sun::star::uno::XComponentContext > m_xContext;
-    com::sun::star::uno::Reference < XCharacterClassification > xUCI;
 
     com::sun::star::uno::Reference < XCharacterClassification > SAL_CALL
     getLocaleSpecificCharacterClassification(const com::sun::star::lang::Locale& rLocale) throw(com::sun::star::uno::RuntimeException);
     sal_Bool SAL_CALL
     createLocaleSpecificCharacterClassification(const OUString& serviceName, const com::sun::star::lang::Locale& rLocale);
 
+private:
+    std::vector<lookupTableItem*> lookupTable;
+    lookupTableItem *cachedItem;
+
+    com::sun::star::uno::Reference < com::sun::star::uno::XComponentContext > m_xContext;
+    com::sun::star::uno::Reference < XCharacterClassification > xUCI;
+    osl::Mutex maMtx;
 };
 
 } } } }
diff --git a/i18npool/source/characterclassification/characterclassificationImpl.cxx b/i18npool/source/characterclassification/characterclassificationImpl.cxx
index d65b5a5..edcf9db 100644
--- a/i18npool/source/characterclassification/characterclassificationImpl.cxx
+++ b/i18npool/source/characterclassification/characterclassificationImpl.cxx
@@ -47,6 +47,7 @@ OUString SAL_CALL
 CharacterClassificationImpl::toUpper( const OUString& Text, sal_Int32 nPos,
         sal_Int32 nCount, const Locale& rLocale ) throw(RuntimeException)
 {
+    osl::MutexGuard aGuard(&maMtx);
     return getLocaleSpecificCharacterClassification(rLocale)->toUpper(Text, nPos, nCount, rLocale);
 }
 
@@ -54,6 +55,7 @@ OUString SAL_CALL
 CharacterClassificationImpl::toLower( const OUString& Text, sal_Int32 nPos,
         sal_Int32 nCount, const Locale& rLocale ) throw(RuntimeException)
 {
+    osl::MutexGuard aGuard(&maMtx);
     return getLocaleSpecificCharacterClassification(rLocale)->toLower(Text, nPos, nCount, rLocale);
 }
 
@@ -61,6 +63,7 @@ OUString SAL_CALL
 CharacterClassificationImpl::toTitle( const OUString& Text, sal_Int32 nPos,
         sal_Int32 nCount, const Locale& rLocale ) throw(RuntimeException)
 {
+    osl::MutexGuard aGuard(&maMtx);
     return getLocaleSpecificCharacterClassification(rLocale)->toTitle(Text, nPos, nCount, rLocale);
 }
 
@@ -68,6 +71,7 @@ sal_Int16 SAL_CALL
 CharacterClassificationImpl::getType( const OUString& Text, sal_Int32 nPos )
         throw(RuntimeException)
 {
+    osl::MutexGuard aGuard(&maMtx);
     if (xUCI.is())
         return xUCI->getType(Text, nPos);
     throw RuntimeException();
@@ -77,6 +81,7 @@ sal_Int16 SAL_CALL
 CharacterClassificationImpl::getCharacterDirection( const OUString& Text, sal_Int32 nPos )
         throw(RuntimeException)
 {
+    osl::MutexGuard aGuard(&maMtx);
     if (xUCI.is())
         return xUCI->getCharacterDirection(Text, nPos);
     throw RuntimeException();
@@ -86,6 +91,7 @@ sal_Int16 SAL_CALL
 CharacterClassificationImpl::getScript( const OUString& Text, sal_Int32 nPos )
         throw(RuntimeException)
 {
+    osl::MutexGuard aGuard(&maMtx);
     if (xUCI.is())
         return xUCI->getScript(Text, nPos);
     throw RuntimeException();
@@ -95,6 +101,7 @@ sal_Int32 SAL_CALL
 CharacterClassificationImpl::getCharacterType( const OUString& Text, sal_Int32 nPos,
         const Locale& rLocale ) throw(RuntimeException)
 {
+    osl::MutexGuard aGuard(&maMtx);
     return getLocaleSpecificCharacterClassification(rLocale)->getCharacterType(Text, nPos, rLocale);
 }
 
@@ -102,6 +109,7 @@ sal_Int32 SAL_CALL
 CharacterClassificationImpl::getStringType( const OUString& Text, sal_Int32 nPos,
         sal_Int32 nCount, const Locale& rLocale ) throw(RuntimeException)
 {
+    osl::MutexGuard aGuard(&maMtx);
     return getLocaleSpecificCharacterClassification(rLocale)->getStringType(Text, nPos, nCount, rLocale);
 }
 
@@ -111,6 +119,7 @@ ParseResult SAL_CALL CharacterClassificationImpl::parseAnyToken(
         sal_Int32 contCharTokenType, const OUString& userDefinedCharactersCont )
         throw(RuntimeException)
 {
+    osl::MutexGuard aGuard(&maMtx);
     return getLocaleSpecificCharacterClassification(rLocale)->parseAnyToken(Text, nPos, rLocale,
             startCharTokenType,userDefinedCharactersStart,
             contCharTokenType, userDefinedCharactersCont);
@@ -123,6 +132,7 @@ ParseResult SAL_CALL CharacterClassificationImpl::parsePredefinedToken(
         const OUString& userDefinedCharactersStart, sal_Int32 contCharTokenType,
         const OUString& userDefinedCharactersCont ) throw(RuntimeException)
 {
+    osl::MutexGuard aGuard(&maMtx);
     return getLocaleSpecificCharacterClassification(rLocale)->parsePredefinedToken(
             nTokenType, Text, nPos, rLocale, startCharTokenType, userDefinedCharactersStart,
             contCharTokenType, userDefinedCharactersCont);
commit fef13dbc4ec18e35af7b787567fabd0c11f950f4
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Thu Nov 7 13:21:13 2013 -0500

    Make this thread safe too.
    
    Change-Id: Ic8508f693f8a6e9bae513d6b5b6eaaaae618194b

diff --git a/sc/inc/mtvelements.hxx b/sc/inc/mtvelements.hxx
index a1532d4..e5efbf1 100644
--- a/sc/inc/mtvelements.hxx
+++ b/sc/inc/mtvelements.hxx
@@ -17,6 +17,7 @@
 #include "editeng/editobj.hxx"
 #include "calcmacros.hxx"
 #include "postit.hxx"
+#include "osl/mutex.hxx"
 
 #if DEBUG_COLUMN_STORAGE
 #ifdef NDEBUG
@@ -138,6 +139,7 @@ class ColumnBlockPositionSet
 
     ScDocument& mrDoc;
     TablesType maTables;
+    osl::Mutex maMtxTables;
 
 public:
     ColumnBlockPositionSet(ScDocument& rDoc);
diff --git a/sc/source/core/data/mtvelements.cxx b/sc/source/core/data/mtvelements.cxx
index 222aabd..5a94606 100644
--- a/sc/source/core/data/mtvelements.cxx
+++ b/sc/source/core/data/mtvelements.cxx
@@ -30,6 +30,8 @@ ColumnBlockPositionSet::ColumnBlockPositionSet(ScDocument& rDoc) : mrDoc(rDoc) {
 
 ColumnBlockPosition* ColumnBlockPositionSet::getBlockPosition(SCTAB nTab, SCCOL nCol)
 {
+    osl::MutexGuard aGuard(&maMtxTables);
+
     TablesType::iterator itTab = maTables.find(nTab);
     if (itTab == maTables.end())
     {
commit c6b1b8181a86fe40464a4ede141c7f79c47b9caa
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Thu Nov 7 13:14:57 2013 -0500

    Guard access to external ref manager instance.
    
    Change-Id: Ie3208844b523463954c482d080f02d726ae749f9

diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 09f1466..08ba3a2 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -39,6 +39,7 @@
 #include "calcmacros.hxx"
 #include <tools/fract.hxx>
 #include <tools/gen.hxx>
+#include "osl/mutex.hxx"
 
 #include <memory>
 #include <map>
@@ -298,7 +299,9 @@ private:
     ::std::auto_ptr<ScDocProtection> pDocProtection;
     ::std::auto_ptr<ScClipParam>     mpClipParam;
 
-    ::std::auto_ptr<ScExternalRefManager> pExternalRefMgr;
+    boost::scoped_ptr<ScExternalRefManager> mpExternalRefMgr;
+    mutable osl::Mutex maMtxExternalRefMgr;
+
     ::std::auto_ptr<ScMacroManager> mpMacroMgr;
 
 
@@ -661,7 +664,7 @@ public:
                                     const OUString& aFileName,
                                     const OUString& aTabName );
 
-    bool            HasExternalRefManager() const { return pExternalRefMgr.get(); }
+    SC_DLLPUBLIC bool HasExternalRefManager() const;
     SC_DLLPUBLIC ScExternalRefManager* GetExternalRefManager() const;
     bool            IsInExternalReferenceMarking() const;
     void            MarkUsedExternalReferences();
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index 23a4bcf..846b5c8 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -150,7 +150,7 @@ ScDocument::ScDocument( ScDocumentMode eMode, SfxObjectShell* pDocShell ) :
         pCacheFieldEditEngine( NULL ),
         pDocProtection( NULL ),
         mpClipParam( NULL),
-        pExternalRefMgr( NULL ),
+        mpExternalRefMgr( NULL ),
         mpMacroMgr( NULL ),
         pViewOptions( NULL ),
         pDocOptions( NULL ),
@@ -384,7 +384,7 @@ ScDocument::~ScDocument()
     mxFormulaParserPool.reset();
     // Destroy the external ref mgr instance here because it has a timer
     // which needs to be stopped before the app closes.
-    pExternalRefMgr.reset();
+    mpExternalRefMgr.reset();
 
     ScAddInAsync::RemoveDocument( this );
     ScAddInListener::RemoveDocument( this );
diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx
index 73f8d71..67fda15 100644
--- a/sc/source/core/data/documen3.cxx
+++ b/sc/source/core/data/documen3.cxx
@@ -582,30 +582,41 @@ bool ScDocument::LinkExternalTab( SCTAB& rTab, const OUString& aDocTab,
     return true;
 }
 
+bool ScDocument::HasExternalRefManager() const
+{
+    osl::MutexGuard aGuard(&maMtxExternalRefMgr);
+    return mpExternalRefMgr.get();
+}
+
 ScExternalRefManager* ScDocument::GetExternalRefManager() const
 {
+    osl::MutexGuard aGuard(&maMtxExternalRefMgr);
+
     ScDocument* pThis = const_cast<ScDocument*>(this);
-    if (!pExternalRefMgr.get())
-        pThis->pExternalRefMgr.reset( new ScExternalRefManager( pThis));
+    if (!mpExternalRefMgr.get())
+        pThis->mpExternalRefMgr.reset( new ScExternalRefManager( pThis));
 
-    return pExternalRefMgr.get();
+    return mpExternalRefMgr.get();
 }
 
 bool ScDocument::IsInExternalReferenceMarking() const
 {
-    return pExternalRefMgr.get() && pExternalRefMgr->isInReferenceMarking();
+    osl::MutexGuard aGuard(&maMtxExternalRefMgr);
+    return mpExternalRefMgr.get() && mpExternalRefMgr->isInReferenceMarking();
 }
 
 void ScDocument::MarkUsedExternalReferences()
 {
-    if (!pExternalRefMgr.get())
+    osl::MutexGuard aGuard(&maMtxExternalRefMgr);
+
+    if (!mpExternalRefMgr.get())
         return;
-    if (!pExternalRefMgr->hasExternalData())
+    if (!mpExternalRefMgr->hasExternalData())
         return;
     // Charts.
-    pExternalRefMgr->markUsedByLinkListeners();
+    mpExternalRefMgr->markUsedByLinkListeners();
     // Formula cells.
-    pExternalRefMgr->markUsedExternalRefCells();
+    mpExternalRefMgr->markUsedExternalRefCells();
 
     /* NOTE: Conditional formats and validation objects are marked when
      * collecting them during export. */
commit 8856eb9e759b41a6115de71c86fd787903374ea5
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Thu Nov 7 13:01:40 2013 -0500

    Move the API guard out of the worker threads onto the manager thread.
    
    Just set this once before spawning multiple worker threads.
    
    Change-Id: I9cb60721f633f939d4a95f1d80e2ed8e4542a8fa

diff --git a/sc/source/filter/oox/formulabuffer.cxx b/sc/source/filter/oox/formulabuffer.cxx
index c3e1d24..f58e9f7 100644
--- a/sc/source/filter/oox/formulabuffer.cxx
+++ b/sc/source/filter/oox/formulabuffer.cxx
@@ -107,7 +107,6 @@ void applyCellFormulas(
     ScDocumentImport& rDoc, SvNumberFormatter& rFormatter,
     const std::vector<FormulaBuffer::TokenAddressItem>& rCells )
 {
-    ScExternalRefManager::ApiGuard aExtRefGuard(&rDoc.getDoc());
     std::vector<FormulaBuffer::TokenAddressItem>::const_iterator it = rCells.begin(), itEnd = rCells.end();
     for (; it != itEnd; ++it)
     {
@@ -225,8 +224,11 @@ void FormulaBuffer::FinalizeThread::execute()
 {
     ScDocumentImport& rDoc = mrParent.getDocImport();
     rDoc.getDoc().SetAutoNameCache(new ScAutoNameCache(&rDoc.getDoc()));
+    ScExternalRefManager::ApiGuard aExtRefGuard(&rDoc.getDoc());
+
     SCTAB nTabCount = rDoc.getDoc().GetTableCount();
 
+    // Fetch all the formulas to process first.
     std::vector<SheetItem> aSheetItems;
     aSheetItems.reserve(nTabCount);
     for (SCTAB nTab = 0; nTab < nTabCount; ++nTab)
@@ -238,6 +240,10 @@ void FormulaBuffer::FinalizeThread::execute()
 
     std::vector<SheetItem>::iterator it = aSheetItems.begin(), itEnd = aSheetItems.end();
 
+    // TODO: Right now we are spawning multiple threads all at once and block
+    // on them all at once.  Any more clever thread management would require
+    // use of condition variables which our own osl thread framework seems to
+    // lack.
     while (it != itEnd)
     {
         for (size_t i = 0; i < mnThreadCount; ++i)
commit 40a465add55251d4719f8241232cd001fa0d3420
Author: Michael Stahl <mstahl at redhat.com>
Date:   Mon Nov 11 13:09:34 2013 +0100

    filter config: fix MIME types for MacWrite and FreeHand
    
    The type "application/macwrite" does not appear to exist, but
    "application/macwriteii" is officially registered at IANA:
    https://www.iana.org/assignments/media-types/application/macwriteii
    
    For Freehand the "application/x-freehand" has just 6 hits on Google
    whereas Adobe recommends "image/x-freehand" on
    https://www.adobe.com/support/config.html
    
    Change-Id: I36d498888601778b1359ff58ee60b25af436a74e
    Reviewed-on: https://gerrit.libreoffice.org/6639
    Tested-by: Fridrich Strba <fridrich at documentfoundation.org>
    Reviewed-by: Fridrich Strba <fridrich at documentfoundation.org>

diff --git a/filter/source/config/fragments/types/draw_Freehand_Document.xcu b/filter/source/config/fragments/types/draw_Freehand_Document.xcu
index 1cc887e..4430854 100644
--- a/filter/source/config/fragments/types/draw_Freehand_Document.xcu
+++ b/filter/source/config/fragments/types/draw_Freehand_Document.xcu
@@ -2,7 +2,7 @@
             <prop oor:name="DetectService"><value>com.sun.star.comp.Draw.FreehandImportFilter</value></prop>
             <prop oor:name="URLPattern"/>
             <prop oor:name="Extensions"><value>fh fh1 fh2 fh3 fh4 fh5 fh6 fh7 fh8 fh9 fh10 fh11</value></prop>
-            <prop oor:name="MediaType"><value>application/x-freehand</value></prop>
+            <prop oor:name="MediaType"><value>image/x-freehand</value></prop>
             <prop oor:name="Preferred"><value>true</value></prop>
             <prop oor:name="PreferredFilter"><value>Freehand Document</value></prop>
             <prop oor:name="UIName">
diff --git a/filter/source/config/fragments/types/writer_MacWrite.xcu b/filter/source/config/fragments/types/writer_MacWrite.xcu
index fa1882b..9be82f1 100644
--- a/filter/source/config/fragments/types/writer_MacWrite.xcu
+++ b/filter/source/config/fragments/types/writer_MacWrite.xcu
@@ -19,7 +19,7 @@
         <prop oor:name="DetectService"><value>com.sun.star.comp.Writer.MWAWImportFilter</value></prop>
         <prop oor:name="URLPattern"/>
         <prop oor:name="Extensions"><value>mw mcw</value></prop>
-        <prop oor:name="MediaType"><value>application/macwrite</value></prop>
+        <prop oor:name="MediaType"><value>application/macwriteii</value></prop>
         <prop oor:name="Preferred"><value>true</value></prop>
         <prop oor:name="PreferredFilter"><value>MacWrite</value></prop>
         <prop oor:name="UIName">
commit a2505ae7317fe6e995a8ad52fefe5079c48f9d6f
Author: Stephan Bergmann <sbergman at redhat.com>
Date:   Mon Nov 11 16:49:40 2013 +0100

    SAL_WARN_UNUSED INetURLObject
    
    Change-Id: Ia9af3b76c2a2ac654b02c1502aa2d0c2c987fbf2

diff --git a/basic/source/uno/namecont.cxx b/basic/source/uno/namecont.cxx
index 2ce1cb9..f3b32d9 100644
--- a/basic/source/uno/namecont.cxx
+++ b/basic/source/uno/namecont.cxx
@@ -1143,7 +1143,6 @@ void SfxLibraryContainer::init_Impl( const OUString& rInitialDocumentURL,
                         if( aLibName == aStandardStr )
                         {
                             SfxLibrary* pImplLib = getImplLib( aStandardStr );
-                            INetURLObject aStandardFolderInetObj( pImplLib->maStorageURL );
                             OUString aStandardFolder = pImplLib->maStorageURL;
                             mxSFI->kill( aStandardFolder );
                         }
diff --git a/cui/source/dialogs/hldoctp.cxx b/cui/source/dialogs/hldoctp.cxx
index 1353038..865b0e5 100644
--- a/cui/source/dialogs/hldoctp.cxx
+++ b/cui/source/dialogs/hldoctp.cxx
@@ -93,8 +93,6 @@ SvxHyperlinkDocTp::~SvxHyperlinkDocTp ()
 
 void SvxHyperlinkDocTp::FillDlgFields(const OUString& rStrURL)
 {
-    INetURLObject aURL(rStrURL);
-
     sal_Int32 nPos = rStrURL.indexOf(sHash);
     // path
     maCbbPath.SetText ( rStrURL.copy( 0, ( nPos == -1 ? rStrURL.getLength() : nPos ) ) );
diff --git a/cui/source/dialogs/hlmailtp.cxx b/cui/source/dialogs/hlmailtp.cxx
index 0fa2688..cfc990a 100644
--- a/cui/source/dialogs/hlmailtp.cxx
+++ b/cui/source/dialogs/hlmailtp.cxx
@@ -94,7 +94,6 @@ SvxHyperlinkMailTp::~SvxHyperlinkMailTp ()
 
 void SvxHyperlinkMailTp::FillDlgFields(const OUString& rStrURL)
 {
-    INetURLObject aURL(rStrURL);
     OUString aStrScheme = GetSchemeFromURL(rStrURL);
 
     // set URL-field and additional controls
diff --git a/include/tools/urlobj.hxx b/include/tools/urlobj.hxx
index 53ea84c..88b8ecd 100644
--- a/include/tools/urlobj.hxx
+++ b/include/tools/urlobj.hxx
@@ -105,7 +105,7 @@ enum INetProtocol
     INET_PROT_END = 35
 };
 
-class TOOLS_DLLPUBLIC INetURLObject
+class TOOLS_DLLPUBLIC SAL_WARN_UNUSED INetURLObject
 {
 public:
     // Get- and Set-Methods:
diff --git a/sfx2/source/doc/doctempl.cxx b/sfx2/source/doc/doctempl.cxx
index e52d6c5..ccb9f26 100644
--- a/sfx2/source/doc/doctempl.cxx
+++ b/sfx2/source/doc/doctempl.cxx
@@ -607,9 +607,6 @@ sal_Bool SfxDocumentTemplates::CopyOrMove
                                   aTitle,
                                   pSource->GetTargetURL() ) )
     {
-
-        INetURLObject aSourceObj( pSource->GetTargetURL() );
-
         OUString aNewTargetURL = GetTemplateTargetURLFromComponent( pTargetRgn->GetTitle(), aTitle );
         if ( aNewTargetURL.isEmpty() )
             return sal_False;
diff --git a/svtools/source/contnr/fileview.cxx b/svtools/source/contnr/fileview.cxx
index 97d2df3..1b5df88 100644
--- a/svtools/source/contnr/fileview.cxx
+++ b/svtools/source/contnr/fileview.cxx
@@ -2446,8 +2446,6 @@ OUString SvtFileView_Impl::FolderInserted( const OUString& rURL, const OUString&
     pData->mbIsFolder = sal_True;
     pData->maTargetURL   = rURL;
 
-    INetURLObject aURLObj( rURL );
-
     ::svtools::VolumeInfo aVolInfo;
     pData->maType = SvFileInformationManager::GetFolderDescription( aVolInfo );
     pData->maImage = SvFileInformationManager::GetFolderImage( aVolInfo, sal_False );
diff --git a/svtools/source/control/inettbc.cxx b/svtools/source/control/inettbc.cxx
index f87f783..362394c 100644
--- a/svtools/source/control/inettbc.cxx
+++ b/svtools/source/control/inettbc.cxx
@@ -478,7 +478,6 @@ OUString SvtURLBox::ParseSmart( OUString aText, OUString aBaseURL, const OUStrin
     if( !SvtURLBox_Impl::TildeParsing( aText, aBaseURL ) )
         return OUString();
 
-    INetURLObject aURLObject;
     if( !aBaseURL.isEmpty() )
     {
         INetProtocol eBaseProt = INetURLObject::CompareProtocolScheme( aBaseURL );
diff --git a/svx/source/gallery2/galtheme.cxx b/svx/source/gallery2/galtheme.cxx
index e52fafc..d82d743 100644
--- a/svx/source/gallery2/galtheme.cxx
+++ b/svx/source/gallery2/galtheme.cxx
@@ -1291,7 +1291,6 @@ SvStream& GalleryTheme::WriteData( SvStream& rOStm ) const
 {
     const INetURLObject aRelURL1( GetParent()->GetRelativeURL() );
     const INetURLObject aRelURL2( GetParent()->GetUserURL() );
-    INetURLObject       aNewURL, aTempURL;
     sal_uInt32          nCount = GetObjectCount();
     sal_Bool                bRel;
 
diff --git a/sw/source/ui/app/docsh2.cxx b/sw/source/ui/app/docsh2.cxx
index 05bbbaf..4e449e1 100644
--- a/sw/source/ui/app/docsh2.cxx
+++ b/sw/source/ui/app/docsh2.cxx
@@ -1388,9 +1388,6 @@ sal_uLong SwDocShell::LoadStylesFromFile( const OUString& rURL,
 {
     sal_uLong nErr = 0;
 
-    // Create a URL from filename
-    INetURLObject aURLObj( rURL );
-
     // Set filter:
     OUString sFactory(OUString::createFromAscii(SwDocShell::Factory().GetShortName()));
     SfxFilterMatcher aMatcher( sFactory );
commit d4fd1c0c38179967166f64342d216e46d7f4d6d3
Author: Michael Stahl <mstahl at redhat.com>
Date:   Mon Nov 11 13:44:36 2013 +0100

    get-bugzilla-attachments-by-mimetype: more launchpad fixes
    
    - look at more interesting packages on lanuchpad, not just libreoffice.
    - the searchTasks method by default does not return closed tasks,
      and there does not appear to be a documented wild card search,
      so stupidly enumerate all possible status.
    
    Change-Id: I51691506874722a1d8eea4755513edf50164cf9d

diff --git a/bin/get-bugzilla-attachments-by-mimetype b/bin/get-bugzilla-attachments-by-mimetype
index 05a24e7..6655ea8 100755
--- a/bin/get-bugzilla-attachments-by-mimetype
+++ b/bin/get-bugzilla-attachments-by-mimetype
@@ -182,40 +182,41 @@ def get_launchpad_bugs(prefix):
     ubuntu = launchpad.distributions["ubuntu"]
 
     #since searching bugs having attachments with specific mimetypes is not available in launchpad API
-    #we're iterating over all bugs of the libreoffice source package
-    libo = ubuntu.getSourcePackage(name="libreoffice")
-    libobugs = libo.searchTasks()
-
-    for bugtask in libobugs:
-        bug = bugtask.bug
-        id = str(bug.id)
-        print("parsing " + id + " status: " + bugtask.status + " title: " + bug.title[:50])
-        attachmentid = 0
-        for attachment in bug.attachments:
-            attachmentid += 1
-            handle = attachment.data.open()
-            if not handle.content_type in mimetypes:
-                #print "skipping"
-                continue
-
-            suffix = mimetypes[handle.content_type]
-            if not os.path.isdir(suffix):
-                try:
-                    os.mkdir(suffix)
-                except:
-                    pass
-
-            download = suffix + '/' + prefix + id + '-' + str(attachmentid) + '.' + suffix
-
-            if os.path.isfile(download):
-                print("assuming " + id + " is up to date")
-                break
+    #we're iterating over all bugs of the most interesting source packages
+    for pkg in ["libreoffice", "openoffice.org", "abiword", "gnumeric", "koffice", "calligra"]:
+        srcpkg = ubuntu.getSourcePackage(name=pkg)
+        pkgbugs = srcpkg.searchTasks(status=["New", "Fix Committed", "Invalid", "Won't Fix", "Confirmed", "Triaged", "In Progress", "Incomplete", "Incomplete (with response)", "Incomplete (without response)", "Fix Released", "Opinion", "Expired"])
+
+        for bugtask in pkgbugs:
+            bug = bugtask.bug
+            id = str(bug.id)
+            print("parsing " + id + " status: " + bugtask.status + " title: " + bug.title[:50])
+            attachmentid = 0
+            for attachment in bug.attachments:
+                attachmentid += 1
+                handle = attachment.data.open()
+                if not handle.content_type in mimetypes:
+                    #print "skipping"
+                    continue
+
+                suffix = mimetypes[handle.content_type]
+                if not os.path.isdir(suffix):
+                    try:
+                        os.mkdir(suffix)
+                    except:
+                        pass
+
+                download = suffix + '/' + prefix + id + '-' + str(attachmentid) + '.' + suffix
+
+                if os.path.isfile(download):
+                    print("assuming " + id + " is up to date")
+                    break
 
-            print('mimetype is ' + handle.content_type + ' downloading as ' + download)
+                print('mimetype is ' + handle.content_type + ' downloading as ' + download)
 
-            f = open(download, "w")
-            f.write(handle.read())
-            f.close()
+                f = open(download, "w")
+                f.write(handle.read())
+                f.close()
 
 freedesktop = 'http://bugs.freedesktop.org/buglist.cgi'
 abisource = 'http://bugzilla.abisource.com/buglist.cgi' #added for abiword
commit bad960e65f4d00315ea7c12cc00b84b26680eb9d
Author: Michael Stahl <mstahl at redhat.com>
Date:   Mon Nov 11 12:45:40 2013 +0100

    get-bugzilla-attachments-by-mimetype: better test for existing file
    
    Change-Id: I208a74d11945986d0712970999dbd33c03efe488

diff --git a/bin/get-bugzilla-attachments-by-mimetype b/bin/get-bugzilla-attachments-by-mimetype
index 4e588af..05a24e7 100755
--- a/bin/get-bugzilla-attachments-by-mimetype
+++ b/bin/get-bugzilla-attachments-by-mimetype
@@ -98,6 +98,11 @@ def get_novell_bug_via_xml(url, mimetype, prefix, suffix):
 
             attachmentid += 1
 
+            download = suffix + '/' + prefix + id + '-' + str(attachmentid) + '.' + suffix
+            if os.path.isfile(download):
+                print("assuming " + download + " is up to date")
+                continue
+
             realAttachmentId = match.group(1)
             handle = urlopen_retry(novellattach + realAttachmentId)
             if not handle:
@@ -115,7 +120,6 @@ def get_novell_bug_via_xml(url, mimetype, prefix, suffix):
                 print("skipping")
                 continue
 
-            download = suffix + '/' + prefix + id + '-' + str(attachmentid) + '.' + suffix
             print('downloading as ' + download)
             f = open(download, 'wb')
             f.write(handle.read())
commit 3e9d164a06d60e756dffad4dd18795796348e97e
Author: Michael Stahl <mstahl at redhat.com>
Date:   Sun Nov 10 19:58:58 2013 +0100

    get-bugzilla-attachments-by-mimetype: add some missing mime types
    
    ... which are officially registered on
    https://www.iana.org/assignments/media-types/application
    
    ... plus some more non-standard ones for FreeHand, Keynote, ClarisWorks.
    
    For Apple Keynote there are 2 different ones that appear to be widely
    used.
    
    Change-Id: I26d4a85733a744188cc87a78fdba0d9d3f44da96

diff --git a/bin/get-bugzilla-attachments-by-mimetype b/bin/get-bugzilla-attachments-by-mimetype
index 15864cf..4e588af 100755
--- a/bin/get-bugzilla-attachments-by-mimetype
+++ b/bin/get-bugzilla-attachments-by-mimetype
@@ -271,11 +271,21 @@ mimetypes = {
     'application/msword': 'doc',
     'application/vnd.ms-powerpoint': 'ppt',
     'application/vnd.ms-excel': 'xls',
+    'application/vnd.ms-excel.sheet.binary.macroEnabled.12': 'xlsb',
+    'application/vnd.ms-excel.sheet.macroEnabled.12': 'xlsm',
+    'application/vnd.ms-excel.template.macroEnabled.12': 'xltm',
+    'application/vnd.ms-powerpoint.presentation.macroEnabled.12': 'pptm',
+    'application/vnd.ms-powerpoint.slide.macroEnabled.12': 'sldm',
+    'application/vnd.ms-powerpoint.slideshow.macroEnabled.12': 'ppsm',
+    'application/vnd.ms-powerpoint.template.macroEnabled.12': 'potm',
+    'application/vnd.ms-word.document.macroEnabled.12': 'docm',
+    'application/vnd.ms-word.template.macroEnabled.12': 'dotm',
     'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'xlsx',
     'application/vnd.openxmlformats-officedocument.spreadsheetml.template': 'xltx',
     'application/vnd.openxmlformats-officedocument.presentationml.presentation': 'pptx',
     'application/vnd.openxmlformats-officedocument.presentationml.template': 'ppotx',
     'application/vnd.openxmlformats-officedocument.presentationml.slideshow': 'ppsx',
+    'application/vnd.openxmlformats-officedocument.presentationml.slide': 'sldx',
     'application/vnd.openxmlformats-officedocument.wordprocessingml.document': 'docx',
     'application/vnd.openxmlformats-officedocument.wordprocessingml.template': 'dotx',
     'application/vnd.visio': 'vsd',
@@ -287,6 +297,7 @@ mimetypes = {
     'text/html': 'html',
     'application/docbook+xml': 'docbook',
 # misc
+    'text/csv': 'csv',
     'text/spreadsheet': 'slk',
     'application/vnd.corel-draw': 'cdr',
     'application/vnd.lotus-wordpro': 'lwp',
@@ -294,6 +305,10 @@ mimetypes = {
     'application/vnd.wordperfect': 'wpd',
     'application/wordperfect5.1': 'wpd',
     'application/vnd.ms-works': 'wps',
+    'application/clarisworks' : 'cwk',
+    'application/macwriteii' : 'mw',
+    'application/vnd.apple.keynote': 'key',
+    'application/x-iwork-keynote-sffkey': 'key',
     'application/x-hwp': 'hwp',
     'application/x-aportisdoc': 'pdb',
     'application/x-pocket-word': 'psw',
@@ -314,6 +329,7 @@ mimetypes = {
     'application/vnd.stardivision.writer': 'sdw5',
     'application/vnd.stardivision.writer-global': 'sgl5',
 # relatively uncommon image mimetypes
+    'image/x-freehand': 'fh',
     'image/cgm': 'cgm',
     'image/tiff': 'tiff',
     'image/vnd.dxf': 'dxf',
commit fdb747ff8c4653d3e94192693f1080398ae20339
Author: Michael Stahl <mstahl at redhat.com>
Date:   Sun Nov 10 19:17:17 2013 +0100

    get-bugzilla-attachments-by-mimetype: more Python 3 in exception handler
    
    ... and also fix the print functions that shouldn't output a newline.
    
    Change-Id: Ifd866cb33b3ef9a2e83625ed03d5cb836c1ba56b

diff --git a/bin/get-bugzilla-attachments-by-mimetype b/bin/get-bugzilla-attachments-by-mimetype
index e3fb177..15864cf 100755
--- a/bin/get-bugzilla-attachments-by-mimetype
+++ b/bin/get-bugzilla-attachments-by-mimetype
@@ -18,6 +18,7 @@
 #
 #where X is the n'th attachment of that type in the bug
 
+from __future__ import print_function
 import feedparser
 import base64
 import re
@@ -40,7 +41,7 @@ def urlopen_retry(url):
         try:
             return urlopen(url)
         except IOError as e:
-            print("caught IOError: " + e)
+            print("caught IOError: " + str(e))
             if maxretries == i:
                 raise
             print("retrying...")
@@ -51,17 +52,17 @@ def get_from_bug_url_via_xml(url, mimetype, prefix, suffix):
     if os.path.isfile(suffix + '/' + prefix + id + '-1.' + suffix):
         print("assuming " + id + " is up to date")
     else:
-        print("parsing", id)
+        print("parsing " + id)
         sock = urlopen_retry(url+"&ctype=xml")
         dom = minidom.parse(sock)
         sock.close()
         attachmentid=0
         for attachment in dom.getElementsByTagName('attachment'):
             attachmentid += 1
-            print(" mimetype is")
+            print(" mimetype is", end=' ')
             for node in attachment.childNodes:
                 if node.nodeName == 'type':
-                    print(node.firstChild.nodeValue)
+                    print(node.firstChild.nodeValue, end=' ')
                     if node.firstChild.nodeValue.lower() != mimetype.lower():
                         print('skipping')
                         break
@@ -102,14 +103,14 @@ def get_novell_bug_via_xml(url, mimetype, prefix, suffix):
             if not handle:
                 print("attachment %s is not accessible" % realAttachmentId)
                 continue
-            print(" mimetype is")
+            print(" mimetype is", end=' ')
 
             info = handle.info()
             if info.get_content_type:
                 remoteMime = info.get_content_type()
             else:
                 remoteMime = info.gettype()
-            print(remoteMime)
+            print(remoteMime, end=' ')
             if remoteMime != mimetype:

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list