/** * \file DepTable.C * This file is part of LyX, the document processor. * Licence details can be found in the file COPYING. * * \author Lars Gullik Bjønnes * \author Jean-Marc Lasgouttes * \author Ben Stanley * * Full author contact details are available in file CREDITS. */ #include #include "DepTable.h" #include "debug.h" #include "support/lyxlib.h" #include "support/filetools.h" #include "support/lstrings.h" #include "support/lyxtime.h" #include #include namespace lyx { #ifndef CXX_GLOBAL_CSTD using std::time; #endif using support::FileName; using support::ltrim; using support::onlyFilename; using support::suffixIs; using support::sum; using std::endl; using std::flush; using std::getline; using std::string; using std::ofstream; using std::ifstream; inline bool DepTable::dep_info::changed() const { return crc_prev != crc_cur && crc_cur != 0; } void DepTable::insert(FileName const & f, bool upd) { if (deplist.find(f) == deplist.end()) { dep_info di; di.crc_prev = 0; if (upd) { lyxerr[Debug::DEPEND] << " CRC..." << flush; di.crc_cur = sum(f); lyxerr[Debug::DEPEND] << "done." << endl; struct stat f_info; stat(f.toFilesystemEncoding().c_str(), &f_info); di.mtime_cur = f_info.st_mtime; } else { di.crc_cur = 0; di.mtime_cur = 0; } deplist[f] = di; } else { lyxerr[Debug::DEPEND] << " Already in DepTable" << endl; } } void DepTable::update() { lyxerr[Debug::DEPEND] << "Updating DepTable..." << endl; time_type const start_time = current_time(); DepList::iterator itr = deplist.begin(); while (itr != deplist.end()) { dep_info &di = itr->second; struct stat f_info; if (stat(itr->first.toFilesystemEncoding().c_str(), &f_info) == 0) { if (di.mtime_cur == f_info.st_mtime) { di.crc_prev = di.crc_cur; lyxerr[Debug::DEPEND] << itr->first << " same mtime" << endl; } else { di.crc_prev = di.crc_cur; lyxerr[Debug::DEPEND] << itr->first << " CRC... " << flush; di.crc_cur = sum(itr->first); lyxerr[Debug::DEPEND] << "done" << endl; } } else { // file doesn't exist // remove stale files - if it's re-created, it // will be re-inserted by deplog. lyxerr[Debug::DEPEND] << itr->first << " doesn't exist. removing from DepTable." << endl; DepList::iterator doomed = itr++; deplist.erase(doomed); continue; } if (lyxerr.debugging(Debug::DEPEND)) { if (di.changed()) lyxerr << " +"; lyxerr << endl; } ++itr; } time_type const time_sec = current_time() - start_time; lyxerr[Debug::DEPEND] << "Finished updating DepTable (" << time_sec << " sec)." << endl; } bool DepTable::sumchange() const { DepList::const_iterator cit = deplist.begin(); DepList::const_iterator end = deplist.end(); for (; cit != end; ++cit) { if (cit->second.changed()) return true; } return false; } bool DepTable::haschanged(FileName const & fil) const { DepList::const_iterator cit = deplist.find(fil); if (cit != deplist.end()) { if (cit->second.changed()) return true; } return false; } bool DepTable::extchanged(string const & ext) const { DepList::const_iterator cit = deplist.begin(); DepList::const_iterator end = deplist.end(); for (; cit != end; ++cit) { if (suffixIs(cit->first.absFilename(), ext)) { if (cit->second.changed()) return true; } } return false; } bool DepTable::ext_exist(string const & ext) const { DepList::const_iterator cit = deplist.begin(); DepList::const_iterator end = deplist.end(); for (; cit != end; ++cit) { if (suffixIs(cit->first.absFilename(), ext)) { return true; } } return false; } bool DepTable::exist(FileName const & fil) const { return deplist.find(fil) != deplist.end(); } void DepTable::remove_files_with_extension(string const & suf) { DepList::iterator cit = deplist.begin(); DepList::iterator end = deplist.end(); while (cit != end) { if (suffixIs(cit->first.absFilename(), suf)) { // Can't erase the current iterator, but we // can increment and then erase. // Deplist is a map so only the erased // iterator is invalidated. DepList::iterator doomed = cit++; deplist.erase(doomed); continue; } ++cit; } } void DepTable::remove_file(FileName const & filename) { DepList::iterator cit = deplist.begin(); DepList::iterator end = deplist.end(); while (cit != end) { if (cit->first == filename) { // Can't erase the current iterator, but we // can increment and then erase. // deplist is a map so only the erased // iterator is invalidated. DepList::iterator doomed = cit++; deplist.erase(doomed); continue; } ++cit; } } void DepTable::write(FileName const & f) const { ofstream ofs(f.toFilesystemEncoding().c_str()); DepList::const_iterator cit = deplist.begin(); DepList::const_iterator end = deplist.end(); for (; cit != end; ++cit) { if (lyxerr.debugging(Debug::DEPEND)) { // Store the second (most recently calculated) // CRC value. // The older one is effectively set to 0 upon re-load. lyxerr << "Write dep: " << cit->second.crc_cur << ' ' << cit->second.mtime_cur << ' ' << cit->first << endl; } ofs << cit->second.crc_cur << ' ' << cit->second.mtime_cur << ' ' << cit->first << endl; } } bool DepTable::read(FileName const & f) { ifstream ifs(f.toFilesystemEncoding().c_str()); string nome; dep_info di; // This doesn't change through the loop. di.crc_prev = 0; while (ifs >> di.crc_cur >> di.mtime_cur && getline(ifs, nome)) { nome = ltrim(nome); if (lyxerr.debugging(Debug::DEPEND)) { lyxerr << "Read dep: " << di.crc_cur << ' ' << di.mtime_cur << ' ' << nome << endl; } deplist[FileName(nome)] = di; } return deplist.size(); } } // namespace lyx