From 8b88c3edde87046db0d5898318a7c071cec4c96b Mon Sep 17 00:00:00 2001 From: Enrico Forestieri Date: Mon, 20 Dec 2010 18:15:39 +0000 Subject: [PATCH] Refine fix for bug #7183. Using updateMacros() entails a performance hit when loading a document with really a lot of macros. So, revert to the original strategy of tracking macros at creation time. In order to also account for macros defined in a child document, the child is now loaded by the include inset at construction time instead of after the master has finished loading. This strategy mimics what updateMacros() was accomplishing without incurring in its drawbacks, such that loading time is practically unchanged even with a thousand macros. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@36968 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/Buffer.cpp | 9 +++++++++ src/Buffer.h | 4 ++++ src/insets/InsetInclude.cpp | 24 +++++++++++++++++++++--- src/mathed/MathParser.cpp | 24 ++++++++++++++++++------ 4 files changed, 52 insertions(+), 9 deletions(-) diff --git a/src/Buffer.cpp b/src/Buffer.cpp index f52423d24d..a046124250 100644 --- a/src/Buffer.cpp +++ b/src/Buffer.cpp @@ -820,6 +820,15 @@ bool Buffer::readDocument(Lexer & lex) // read main text bool const res = text().read(lex, errorList, d->inset); + // inform parent buffer about local macros + if (parent()) { + Buffer * pbuf = const_cast(parent()); + UserMacroSet::const_iterator cit = usermacros.begin(); + UserMacroSet::const_iterator end = usermacros.end(); + for (; cit != end; ++cit) + pbuf->usermacros.insert(*cit); + } + usermacros.clear(); updateMacros(); updateMacroInstances(); return res; diff --git a/src/Buffer.h b/src/Buffer.h index e79856609f..d0d787687c 100644 --- a/src/Buffer.h +++ b/src/Buffer.h @@ -542,6 +542,10 @@ public: /// Return macro defined before the inclusion of the child MacroData const * getMacro(docstring const & name, Buffer const & child, bool global = true) const; + /// Collect user macro names at loading time + typedef std::set UserMacroSet; + UserMacroSet usermacros; + /// Replace the inset contents for insets which InsetCode is equal /// to the passed \p inset_code. void changeRefsIfUnique(docstring const & from, docstring const & to, diff --git a/src/insets/InsetInclude.cpp b/src/insets/InsetInclude.cpp index aa38ff6aab..bdb332d9d6 100644 --- a/src/insets/InsetInclude.cpp +++ b/src/insets/InsetInclude.cpp @@ -48,6 +48,8 @@ #include "insets/InsetListingsParams.h" #include "insets/RenderPreview.h" +#include "mathed/MacroTable.h" + #include "support/convert.h" #include "support/debug.h" #include "support/docstream.h" @@ -170,7 +172,8 @@ InsetInclude::InsetInclude(Buffer * buf, InsetCommandParams const & p) if (isListings(params())) { InsetListingsParams listing_params(to_utf8(p["lstparams"])); label_ = createLabel(buffer_, from_utf8(listing_params.getParamValue("label"))); - } + } else if (isInputOrInclude(params()) && buf) + loadIfNeeded(); } @@ -443,18 +446,33 @@ Buffer * InsetInclude::loadIfNeeded() const // Buffer creation is not possible. return 0; + // Set parent before loading, such that macros can be tracked + child->setParent(&buffer()); + if (child->loadLyXFile() != Buffer::ReadSuccess) { failedtoload_ = true; + child->setParent(0); //close the buffer we just opened theBufferList().release(child); return 0; } - + if (!child->errorList("Parse").empty()) { // FIXME: Do something. } + } else { + // The file was already loaded, so, simply + // inform parent buffer about local macros. + Buffer * parent = const_cast(&buffer()); + child->setParent(parent); + MacroNameSet macros; + child->listMacroNames(macros); + MacroNameSet::const_iterator cit = macros.begin(); + MacroNameSet::const_iterator end = macros.end(); + for (; cit != end; ++cit) + parent->usermacros.insert(*cit); } - child->setParent(&buffer()); + // Cache the child buffer. child_buffer_ = child; return child; diff --git a/src/mathed/MathParser.cpp b/src/mathed/MathParser.cpp index f86a762be8..ad52e76105 100644 --- a/src/mathed/MathParser.cpp +++ b/src/mathed/MathParser.cpp @@ -1060,6 +1060,9 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags, cell->push_back(MathAtom(new MathMacroTemplate(buf, name, nargs, 0, MacroTypeDef, vector(), def, display))); + + if (buf && (mode_ & Parse::TRACKMACRO)) + buf->usermacros.insert(name); } else if (t.cs() == "newcommand" || @@ -1105,6 +1108,9 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags, cell->push_back(MathAtom(new MathMacroTemplate(buf, name, nargs, optionals, MacroTypeNewcommand, optionalValues, def, display))); + + if (buf && (mode_ & Parse::TRACKMACRO)) + buf->usermacros.insert(name); } else if (t.cs() == "newcommandx" || @@ -1223,6 +1229,9 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags, cell->push_back(MathAtom(new MathMacroTemplate(buf, name, nargs, optionals, MacroTypeNewcommandx, optionalValues, def, display))); + + if (buf && (mode_ & Parse::TRACKMACRO)) + buf->usermacros.insert(name); } else if (t.cs() == "(") { @@ -1821,14 +1830,17 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags, } else if (t.cs().size()) { - latexkeys const * l = in_word_set(t.cs()); - - if (buf && (mode_ & Parse::TRACKMACRO) && l) - buf->updateMacros(); + bool const no_mhchem = + (t.cs() == "ce" || t.cs() == "cf") + && buf && buf->params().use_mhchem == + BufferParams::package_off; - bool const is_user_macro = - (buf && buf->getMacro(t.cs(), false) != 0); + bool const is_user_macro = no_mhchem || + (buf && (mode_ & Parse::TRACKMACRO + ? buf->usermacros.count(t.cs()) != 0 + : buf->getMacro(t.cs(), false) != 0)); + latexkeys const * l = in_word_set(t.cs()); if (l && !is_user_macro) { if (l->inset == "big") { skipSpaces(); -- 2.39.2