X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FBuffer.cpp;h=620f5c29048fc30e949531918e464caece6ed27f;hb=4ddc9e2501400f8bdc35d4d1fe56f39c49e82115;hp=eb65e811b4588d76aae3a00042a1796de453e4d1;hpb=d11a27a61164a1107c4c1e5a6fa0720ec4a1e14c;p=lyx.git diff --git a/src/Buffer.cpp b/src/Buffer.cpp index eb65e811b4..620f5c2904 100644 --- a/src/Buffer.cpp +++ b/src/Buffer.cpp @@ -154,7 +154,8 @@ typedef vector LabelCache; typedef map RefCache; // A storehouse for the cloned buffers. -std::list cloned_buffers; +typedef list CloneStore; +CloneStore cloned_buffers; } // namespace @@ -200,40 +201,9 @@ public: /// need to regenerate .tex? DepClean dep_clean; - /// is save needed? - mutable bool lyx_clean; - - /// is autosave needed? - mutable bool bak_clean; - - /// is this an unnamed file (New...)? - bool unnamed; - - /// is this an internal bufffer? - bool internal_buffer; - - /// buffer is r/o - bool read_only; - /// name of the file the buffer is associated with. FileName filename; - /** Set to true only when the file is fully loaded. - * Used to prevent the premature generation of previews - * and by the citation inset. - */ - bool file_fully_loaded; - - /// original format of loaded file - int file_format; - - /// if the file was originally loaded from an older format, do - /// we need to back it up still? - bool need_format_backup; - - /// Ignore the parent (e.g. when exporting a child standalone)? - bool ignore_parent; - /// mutable TocBackend toc_backend; @@ -250,8 +220,6 @@ public: /// map from the macro name to the position map, /// which maps the macro definition position to the scope and the MacroData. NamePositionScopeMacroMap macros; - /// This seem to change the way Buffer::getMacro() works - mutable bool macro_lock; /// positions of child buffers in the buffer typedef map BufferPositionMap; @@ -303,25 +271,13 @@ public: // file, and then to construct the Buffer's bibinfo from that. /// A cache for bibliography info mutable BiblioInfo bibinfo_; - /// whether the bibinfo cache is valid - mutable bool bibinfo_cache_valid_; /// Cache of timestamps of .bib files map bibfile_status_; - /// Indicates whether the bibinfo has changed since the last time - /// we ran updateBuffer(), i.e., whether citation labels may need - /// to be updated. - mutable bool cite_labels_valid_; - /// Do we have a bibliography environment? - mutable bool have_bibitems_; /// These two hold the file name and format, written to by /// Buffer::preview and read from by LFUN_BUFFER_VIEW_CACHE. FileName preview_file_; string preview_format_; - /// If there was an error when previewing, on the next preview we do - /// a fresh compile (e.g. in case the user installed a package that - /// was missing). - bool require_fresh_start_; /// Cache the references associated to a label and their positions /// in the buffer. @@ -335,6 +291,81 @@ public: /// PreviewLoader * preview_loader_; + /// If non zero, this buffer is a clone of existing buffer \p cloned_buffer_ + /// This one is useful for preview detached in a thread. + Buffer const * cloned_buffer_; + /// + CloneList_ptr clone_list_; + +private: + /// So we can force access via the accessors. + mutable Buffer const * parent_buffer; + + FileMonitorPtr file_monitor_; + +/// ints and bools are all listed last so as to avoid alignment issues +public: + /// original format of loaded file + int file_format; + + /// are we in the process of exporting this buffer? + mutable bool doing_export; + + /// If there was an error when previewing, on the next preview we do + /// a fresh compile (e.g. in case the user installed a package that + /// was missing). + bool require_fresh_start_; + + /// Indicates whether the bibinfo has changed since the last time + /// we ran updateBuffer(), i.e., whether citation labels may need + /// to be updated. + mutable bool cite_labels_valid_; + /// Do we have a bibliography environment? + mutable bool have_bibitems_; + + /// is save needed? + mutable bool lyx_clean; + + /// is autosave needed? + mutable bool bak_clean; + + /// is this an unnamed file (New...)? + bool unnamed; + + /// is this an internal bufffer? + bool internal_buffer; + + /// buffer is r/o + bool read_only; + + /** Set to true only when the file is fully loaded. + * Used to prevent the premature generation of previews + * and by the citation inset. + */ + bool file_fully_loaded; + + /// if the file was originally loaded from an older format, do + /// we need to back it up still? + bool need_format_backup; + + /// Ignore the parent (e.g. when exporting a child standalone)? + bool ignore_parent; + + /// This seem to change the way Buffer::getMacro() works + mutable bool macro_lock; + + /// has been externally modified? Can be reset by the user. + mutable bool externally_modified_; + + /// whether the bibinfo cache is valid + mutable bool bibinfo_cache_valid_; + +private: + int word_count_; + int char_count_; + int blank_count_; + +public: /// This is here to force the test to be done whenever parent_buffer /// is accessed. Buffer const * parent() const @@ -367,14 +398,6 @@ public: parent_buffer->invalidateBibinfoCache(); } - /// If non zero, this buffer is a clone of existing buffer \p cloned_buffer_ - /// This one is useful for preview detached in a thread. - Buffer const * cloned_buffer_; - /// - CloneList * clone_list_; - /// are we in the process of exporting this buffer? - mutable bool doing_export; - /// compute statistics /// \p from initial position /// \p to points to the end position @@ -397,24 +420,11 @@ public: /// Notify or clear of external modification void fileExternallyModified(bool exists); - /// has been externally modified? Can be reset by the user. - mutable bool externally_modified_; - ///Binding LaTeX lines with buffer positions. //Common routine for LaTeX and Reference errors listing. void traverseErrors(TeXErrors::Errors::const_iterator err, TeXErrors::Errors::const_iterator end, ErrorList & errorList) const; - -private: - /// So we can force access via the accessors. - mutable Buffer const * parent_buffer; - - int word_count_; - int char_count_; - int blank_count_; - - FileMonitorPtr file_monitor_; }; @@ -447,15 +457,15 @@ static FileName createBufferTmpDir() Buffer::Impl::Impl(Buffer * owner, FileName const & file, bool readonly_, Buffer const * cloned_buffer) - : owner_(owner), lyx_clean(true), bak_clean(true), unnamed(false), - internal_buffer(false), read_only(readonly_), filename(file), - file_fully_loaded(false), file_format(LYX_FORMAT), need_format_backup(false), - ignore_parent(false), toc_backend(owner), macro_lock(false), - checksum_(0), wa_(nullptr), gui_(nullptr), undo_(*owner), bibinfo_cache_valid_(false), - cite_labels_valid_(false), have_bibitems_(false), require_fresh_start_(false), - inset(nullptr), preview_loader_(nullptr), cloned_buffer_(cloned_buffer), - clone_list_(nullptr), doing_export(false), - externally_modified_(false), parent_buffer(nullptr), + : owner_(owner), filename(file), toc_backend(owner), checksum_(0), + wa_(nullptr), gui_(nullptr), undo_(*owner), inset(nullptr), + preview_loader_(nullptr), cloned_buffer_(cloned_buffer), + clone_list_(nullptr), parent_buffer(nullptr), file_format(LYX_FORMAT), + doing_export(false), require_fresh_start_(false), cite_labels_valid_(false), + have_bibitems_(false), lyx_clean(true), bak_clean(true), unnamed(false), + internal_buffer(false), read_only(readonly_), file_fully_loaded(false), + need_format_backup(false), ignore_parent(false), macro_lock(false), + externally_modified_(false), bibinfo_cache_valid_(false), word_count_(0), char_count_(0), blank_count_(0) { refreshFileMonitor(); @@ -530,8 +540,8 @@ Buffer::~Buffer() // loop over children for (auto const & p : d->children_positions) { Buffer * child = const_cast(p.first); - if (d->clone_list_->erase(child)) - delete child; + if (d->clone_list_->erase(child)) + delete child; } // if we're the master buffer, then we should get rid of the list // of clones @@ -540,14 +550,15 @@ Buffer::~Buffer() // children still has a reference to this list. But we will try to // continue, rather than shut down. LATTEST(d->clone_list_->empty()); - list::iterator it = + // The clone list itself is empty, but it's still referenced in our list + // of clones. So let's find it and remove it. + CloneStore::iterator it = find(cloned_buffers.begin(), cloned_buffers.end(), d->clone_list_); if (it == cloned_buffers.end()) { // We will leak in this case, but it is safe to continue. LATTEST(false); } else cloned_buffers.erase(it); - delete d->clone_list_; } // FIXME Do we really need to do this right before we delete d? // clear references to children in macro tables @@ -594,8 +605,8 @@ Buffer::~Buffer() Buffer * Buffer::cloneWithChildren() const { BufferMap bufmap; - cloned_buffers.push_back(new CloneList); - CloneList * clones = cloned_buffers.back(); + cloned_buffers.emplace_back(new CloneList); + CloneList_ptr clones = cloned_buffers.back(); cloneWithChildren(bufmap, clones); @@ -608,7 +619,7 @@ Buffer * Buffer::cloneWithChildren() const } -void Buffer::cloneWithChildren(BufferMap & bufmap, CloneList * clones) const +void Buffer::cloneWithChildren(BufferMap & bufmap, CloneList_ptr clones) const { // have we already been cloned? if (bufmap.find(this) != bufmap.end()) @@ -658,8 +669,8 @@ void Buffer::cloneWithChildren(BufferMap & bufmap, CloneList * clones) const Buffer * Buffer::cloneBufferOnly() const { - cloned_buffers.push_back(new CloneList); - CloneList * clones = cloned_buffers.back(); + cloned_buffers.emplace_back(new CloneList); + CloneList_ptr clones = cloned_buffers.back(); Buffer * buffer_clone = new Buffer(fileName().absFileName(), false, this); // The clone needs its own DocumentClass, since running updateBuffer() will @@ -3166,7 +3177,7 @@ Language const * Buffer::language() const } -docstring const Buffer::B_(string const & l10n) const +docstring Buffer::B_(string const & l10n) const { return params().B_(l10n); } @@ -3397,7 +3408,7 @@ vector> const Buffer::prepareBibFilePaths(OutputParams c enc = params().bibFileEncoding(utf8input); bool recorded = false; - for (pair pe : res) { + for (auto const & pe : res) { if (pe.first == path) { recorded = true; break; @@ -3985,7 +3996,7 @@ void Buffer::setInsetLabel(docstring const & label, InsetLabel const * il, InsetLabel const * Buffer::insetLabel(docstring const & label, bool const active) const { - for (auto & rc : masterBuffer()->d->label_cache_) { + for (auto const & rc : masterBuffer()->d->label_cache_) { if (rc.label == label && (rc.active || !active)) return rc.inset; } @@ -4224,91 +4235,6 @@ void Buffer::setGuiDelegate(frontend::GuiBufferDelegate * gui) } - -namespace { - -class AutoSaveBuffer : public ForkedProcess { -public: - /// - AutoSaveBuffer(Buffer const & buffer, FileName const & fname) - : buffer_(buffer), fname_(fname) {} - /// - virtual shared_ptr clone() const - { - return make_shared(*this); - } - /// - int start() - { - command_ = to_utf8(bformat(_("Auto-saving %1$s"), - from_utf8(fname_.absFileName()))); - return run(DontWait); - } -private: - /// - virtual int generateChild(); - /// - Buffer const & buffer_; - FileName fname_; -}; - - -int AutoSaveBuffer::generateChild() -{ -#if defined(__APPLE__) - /* FIXME fork() is not usable for autosave on Mac OS X 10.6 (snow leopard) - * We should use something else like threads. - * - * Since I do not know how to determine at run time what is the OS X - * version, I just disable forking altogether for now (JMarc) - */ - pid_t const pid = -1; -#else - // tmp_ret will be located (usually) in /tmp - // will that be a problem? - // Note that this calls ForkedCalls::fork(), so it's - // ok cross-platform. - pid_t const pid = fork(); - // If you want to debug the autosave - // you should set pid to -1, and comment out the fork. - if (pid != 0 && pid != -1) - return pid; -#endif - - // pid = -1 signifies that lyx was unable - // to fork. But we will do the save - // anyway. - bool failed = false; - TempFile tempfile("lyxautoXXXXXX.lyx"); - tempfile.setAutoRemove(false); - FileName const tmp_ret = tempfile.name(); - if (!tmp_ret.empty()) { - if (!buffer_.writeFile(tmp_ret)) - failed = true; - else if (!tmp_ret.moveTo(fname_)) - failed = true; - } else - failed = true; - - if (failed) { - // failed to write/rename tmp_ret so try writing direct - if (!buffer_.writeFile(fname_)) { - // It is dangerous to do this in the child, - // but safe in the parent, so... - if (pid == -1) // emit message signal. - buffer_.message(_("Autosave failed!")); - } - } - - if (pid == 0) // we are the child so... - _exit(0); - - return pid; -} - -} // namespace - - FileName Buffer::getEmergencyFileName() const { return FileName(d->filename.absFileName() + ".emergency"); @@ -4405,7 +4331,7 @@ Buffer::ExportStatus Buffer::doExport(string const & target, bool put_in_tempdir string & result_file) const { bool const update_unincluded = - params().maintain_unincluded_children + params().maintain_unincluded_children != BufferParams::CM_None && !params().getIncludedChildren().empty(); // (1) export with all included children (omit \includeonly) @@ -4576,8 +4502,9 @@ Buffer::ExportStatus Buffer::doExport(string const & target, bool put_in_tempdir string const ext = theFormats().extension(format); FileName const tmp_result_file(changeExtension(filename, ext)); Converters::RetVal const retval = - converters.convert(this, FileName(filename), tmp_result_file, - FileName(absFileName()), backend_format, format, error_list); + converters.convert(this, FileName(filename), tmp_result_file, + FileName(absFileName()), backend_format, format, + error_list, Converters::none, includeall); if (retval == Converters::KILLED) return ExportCancel; bool success = (retval == Converters::SUCCESS); @@ -4692,7 +4619,7 @@ Buffer::ExportStatus Buffer::doExport(string const & target, bool put_in_tempdir Buffer::ExportStatus Buffer::preview(string const & format) const { bool const update_unincluded = - params().maintain_unincluded_children + params().maintain_unincluded_children != BufferParams::CM_None && !params().getIncludedChildren().empty(); return preview(format, update_unincluded); } @@ -5293,7 +5220,7 @@ void Buffer::Impl::setLabel(ParIterator & it, UpdateType utype) const } -void Buffer::updateBuffer(ParIterator & parit, UpdateType utype) const +void Buffer::updateBuffer(ParIterator & parit, UpdateType utype, bool const deleted) const { // LASSERT: Is it safe to continue here, or should we just return? LASSERT(parit.pit() == 0, /**/); @@ -5339,7 +5266,7 @@ void Buffer::updateBuffer(ParIterator & parit, UpdateType utype) const // now the insets for (auto const & insit : parit->insetList()) { parit.pos() = insit.pos; - insit.inset->updateBuffer(parit, utype); + insit.inset->updateBuffer(parit, utype, deleted || parit->isDeleted(insit.pos)); changed |= insit.inset->isChanged(); }