[LyX features/cleanup/updateMacros3] Refactor the macro tables in Buffer.
Richard Kimberly Heck
rikiheck at lyx.org
Thu Nov 12 00:43:23 UTC 2020
The branch, cleanup/updateMacros3, has been updated.
- Log -----------------------------------------------------------------
commit 10c39c879e99d1263faf56ec03505f3d4fce532f
Author: Richard Kimberly Heck <rikiheck at lyx.org>
Date: Mon Nov 9 18:29:26 2020 -0500
Refactor the macro tables in Buffer.
The use of maps of maps of structs is beyond confusing. Replace that
with a class that hides at least some of the complexity. There is
probably more that could be done along the same lines.
(Note: This fixes a thinko but is otherwise the same as the previous
commit. So it rewrites history.)
(cherry picked from commit dbf24b113ebb559d91b20fd84c7de1b96684d752)
diff --git a/src/Buffer.cpp b/src/Buffer.cpp
index e50fd5c..1901264 100644
--- a/src/Buffer.cpp
+++ b/src/Buffer.cpp
@@ -199,23 +199,54 @@ public:
///
mutable TocBackend toc_backend;
- /// macro tables
- struct MacroDefinition {
- MacroDefinition() {}
- MacroDefinition(DocIterator const & s, MacroData const & m)
- : scope(s), macro(m) {}
- // The SCOPE is really just the last position at which the macro
- // is in force. This will be the end of the file (if there are no
- // children) unless it is in (say) a note, or an inactive branch,
- // in which case it will be the end of that construct.
- DocIterator scope;
- MacroData macro;
+ class MacroTable {
+ public:
+ struct MacroDefinition {
+ MacroDefinition() {}
+ MacroDefinition(DocIterator const & s, MacroData const & m)
+ : scope(s), macro(m) {}
+ // The SCOPE is really just the last position at which the macro
+ // is in force. This will be the end of the file (if there are no
+ // children) unless it is in (say) a note, or an inactive branch,
+ // in which case it will be the end of that construct.
+ DocIterator scope;
+ MacroData macro;
+ };
+ typedef map<DocIterator, MacroDefinition> MacroDefList;
+ typedef map<docstring, MacroDefList> MacroMap;
+
+ pair<bool, MacroDefList const &> getMacroDefinitions(docstring const & name) const
+ {
+ MacroMap::const_iterator it = macro_map_.find(name);
+ if (it == macro_map_.end()) {
+ static MacroDefList dummy;
+ return {false, dummy};
+ }
+ return {true, it->second};
+ }
+
+ set<docstring> getMacroNames() const
+ {
+ set<docstring> names;
+ for (auto const & m : macro_map_)
+ names.insert(m.first);
+ return names;
+ }
+
+ void clear() { macro_map_.clear(); }
+
+ void addMacroDefinition(docstring const & name,
+ DocIterator const & pos,
+ DocIterator const & scope,
+ MacroData const & data)
+ {
+ MacroDefList & m = macro_map_[name];
+ m[pos] = {scope, data};
+ }
+ private:
+ map<docstring, MacroDefList> macro_map_;
};
- typedef map<DocIterator, MacroDefinition> PositionScopeMacroMap;
- typedef map<docstring, PositionScopeMacroMap> MacroMap;
- /// map from the macro name to the position map,
- /// which maps the macro definition position to the scope and the MacroData.
- MacroMap macros;
+ MacroTable macro_table;
/// Each child Buffer is listed in this map, together with where
/// it is first included in this Buffer.
@@ -3592,7 +3623,7 @@ typename M::const_iterator greatest_below(M & m, typename M::key_type const & x)
MacroData const * Buffer::Impl::getBufferMacro(docstring const & name,
DocIterator const & pos) const
{
- LYXERR(Debug::MACROS, "Searching for " << to_ascii(name) << " at " << pos);
+ LYXERR(Debug::MACROS, "Searching for `" << to_ascii(name) << "' at " << pos);
// if paragraphs have no macro context set, pos will be empty
if (pos.empty())
@@ -3603,25 +3634,28 @@ MacroData const * Buffer::Impl::getBufferMacro(docstring const & name,
MacroData const * bestData = nullptr;
// find macro definitions for name
- MacroMap::const_iterator nameIt = macros.find(name);
- if (nameIt != macros.end()) {
+ pair<bool, MacroTable::MacroDefList const &> mdl_pair =
+ macro_table.getMacroDefinitions(name);
+ if (mdl_pair.first) {
+ MacroTable::MacroDefList const & mdl = mdl_pair.second;
// find last definition in front of pos
- PositionScopeMacroMap::const_iterator it
- = greatest_below(nameIt->second, pos);
- if (it != nameIt->second.end()) {
+ MacroTable::MacroDefList::const_iterator it =
+ greatest_below(mdl, pos);
+ if (it != mdl.end()) {
while (true) {
// scope ends behind pos?
if (pos < it->second.scope) {
// Looks good, remember this. If there
// is no external macro behind this,
+ // (i.e., one in a child file), then
// we found the right one already.
bestPos = it->first;
bestData = &it->second.macro;
break;
}
-
+
// try previous macro if there is one
- if (it == nameIt->second.begin())
+ if (it == mdl.begin())
break;
--it;
}
@@ -3808,10 +3842,8 @@ void Buffer::Impl::updateMacros(DocIterator & it, DocIterator & scope)
continue;
// register macro
- // FIXME (Abdel), I don't understand why we pass 'it' here
- // instead of 'macroTemplate' defined above... is this correct?
- macros[macroTemplate.name()][it] =
- Impl::MacroDefinition(scope, MacroData(const_cast<Buffer *>(owner_), it));
+ macro_table.addMacroDefinition(macroTemplate.name(), it, scope,
+ MacroData(const_cast<Buffer *>(owner_), it));
}
// next paragraph
@@ -3842,7 +3874,7 @@ void Buffer::updateMacros() const
#endif
// start with empty table
- d->macros.clear();
+ d->macro_table.clear();
d->children_positions.clear();
d->position_to_children.clear();
@@ -3917,9 +3949,8 @@ void Buffer::listMacroNames(MacroNameSet & macros) const
d->macro_lock = true;
- // loop over macro names
- for (auto const & nameit : d->macros)
- macros.insert(nameit.first);
+ set<docstring> names = d->macro_table.getMacroNames();
+ macros.insert(names.begin(), names.end());
// loop over children
for (auto const & p : d->children_positions) {
-----------------------------------------------------------------------
Summary of changes:
src/Buffer.cpp | 95 +++++++++++++++++++++++++++++++++++++-------------------
1 files changed, 63 insertions(+), 32 deletions(-)
hooks/post-receive
--
Repository for new features
More information about the lyx-cvs
mailing list