]> git.lyx.org Git - lyx.git/blob - src/DepTable.cpp
Avoid full metrics computation with Update:FitCursor
[lyx.git] / src / DepTable.cpp
1 /**
2  * \file DepTable.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Lars Gullik Bjønnes
7  * \author Jean-Marc Lasgouttes
8  * \author Ben Stanley
9  *
10  * Full author contact details are available in file CREDITS.
11  */
12
13 #include <config.h>
14
15 #include "DepTable.h"
16
17 #include "support/debug.h"
18 #include "support/FileName.h"
19 #include "support/lstrings.h"
20 #include "support/lyxtime.h"
21
22 #include <fstream>
23
24 using namespace std;
25 using namespace lyx::support;
26
27 namespace lyx {
28
29
30 inline
31 bool DepTable::dep_info::changed() const
32 {
33         return crc_prev != crc_cur && crc_cur != 0;
34 }
35
36
37 void DepTable::insert(FileName const & f, bool upd)
38 {
39         if (deplist.find(f) == deplist.end()) {
40                 dep_info di;
41                 di.crc_prev = 0;
42                 if (upd && f.exists()) {
43                         LYXERR(Debug::DEPEND, " CRC...");
44                         di.crc_cur = f.checksum();
45                         LYXERR(Debug::DEPEND, "done.");
46                         di.mtime_cur = f.lastModified();
47                 } else {
48                         di.crc_cur = 0;
49                         di.mtime_cur = 0;
50                 }
51                 deplist[f] = di;
52         } else {
53                 LYXERR(Debug::DEPEND, " Already in DepTable");
54         }
55 }
56
57
58 void DepTable::update()
59 {
60         LYXERR(Debug::DEPEND, "Updating DepTable...");
61         time_t const start_time = current_time();
62
63         DepList::iterator itr = deplist.begin();
64         while (itr != deplist.end()) {
65                 FileName const & fn = itr->first;
66                 dep_info &di = itr->second;
67
68                 if (fn.exists()) {
69                         if (di.mtime_cur == fn.lastModified()) {
70                                 di.crc_prev = di.crc_cur;
71                                 LYXERR(Debug::DEPEND, itr->first << " same mtime");
72                         } else {
73                                 di.crc_prev = di.crc_cur;
74                                 LYXERR(Debug::DEPEND, itr->first << " CRC... ");
75                                 di.crc_cur = fn.checksum();
76                                 LYXERR(Debug::DEPEND, "done");
77                         }
78                 } else {
79                         // file doesn't exist
80                         // remove stale files - if it's re-created, it
81                         // will be re-inserted by deplog.
82                         LYXERR(Debug::DEPEND, fn << " doesn't exist. removing from DepTable.");
83                         DepList::iterator doomed = itr++;
84                         deplist.erase(doomed);
85                         continue;
86                 }
87
88                 if (lyxerr.debugging(Debug::DEPEND)) {
89                         if (di.changed())
90                                 lyxerr << " +";
91                         lyxerr << endl;
92                 }
93                 ++itr;
94         }
95         time_t const time_sec = current_time() - start_time;
96         LYXERR(Debug::DEPEND, "Finished updating DepTable ("
97                 << long(time_sec) << " sec).");
98 }
99
100
101 bool DepTable::sumchange() const
102 {
103         DepList::const_iterator cit = deplist.begin();
104         DepList::const_iterator end = deplist.end();
105         for (; cit != end; ++cit) {
106                 if (cit->second.changed())
107                         return true;
108         }
109         return false;
110 }
111
112
113 bool DepTable::haschanged(FileName const & fil) const
114 {
115         DepList::const_iterator cit = deplist.find(fil);
116         if (cit != deplist.end()) {
117                 if (cit->second.changed())
118                         return true;
119         }
120         return false;
121 }
122
123
124 bool DepTable::extchanged(string const & ext) const
125 {
126         DepList::const_iterator cit = deplist.begin();
127         DepList::const_iterator end = deplist.end();
128         for (; cit != end; ++cit) {
129                 if (suffixIs(cit->first.absFileName(), ext)) {
130                         if (cit->second.changed())
131                                 return true;
132                 }
133         }
134         return false;
135 }
136
137
138 bool DepTable::ext_exist(string const & ext) const
139 {
140         DepList::const_iterator cit = deplist.begin();
141         DepList::const_iterator end = deplist.end();
142         for (; cit != end; ++cit) {
143                 if (suffixIs(cit->first.absFileName(), ext))
144                         return true;
145         }
146         return false;
147 }
148
149
150 bool DepTable::exist(FileName const & fil) const
151 {
152         return deplist.find(fil) != deplist.end();
153 }
154
155
156 void DepTable::remove_files_with_extension(string const & suf)
157 {
158         DepList::iterator cit = deplist.begin();
159         DepList::iterator end = deplist.end();
160         while (cit != end) {
161                 if (suffixIs(cit->first.absFileName(), suf)) {
162                         // Can't erase the current iterator, but we
163                         // can increment and then erase.
164                         // Deplist is a map so only the erased
165                         // iterator is invalidated.
166                         DepList::iterator doomed = cit++;
167                         deplist.erase(doomed);
168                         continue;
169                 }
170                 ++cit;
171         }
172 }
173
174
175 void DepTable::remove_file(FileName const & filename)
176 {
177         DepList::iterator cit = deplist.begin();
178         DepList::iterator end = deplist.end();
179         while (cit != end) {
180                 if (cit->first == filename) {
181                         // Can't erase the current iterator, but we
182                         // can increment and then erase.
183                         // deplist is a map so only the erased
184                         // iterator is invalidated.
185                         DepList::iterator doomed = cit++;
186                         deplist.erase(doomed);
187                         continue;
188                 }
189                 ++cit;
190         }
191 }
192
193
194 void DepTable::write(FileName const & f) const
195 {
196         ofstream ofs(f.toFilesystemEncoding().c_str());
197         DepList::const_iterator cit = deplist.begin();
198         DepList::const_iterator end = deplist.end();
199         for (; cit != end; ++cit) {
200                 // Store the second (most recently calculated)
201                 // CRC value.
202                 // The older one is effectively set to 0 upon re-load.
203                 LYXERR(Debug::DEPEND, "Write dep: "
204                        << cit->second.crc_cur << ' '
205                        << cit->second.mtime_cur << ' '
206                        << cit->first);
207
208                 ofs << cit->second.crc_cur << ' '
209                     << cit->second.mtime_cur << ' '
210                     << cit->first << endl;
211         }
212 }
213
214
215 bool DepTable::read(FileName const & f)
216 {
217         ifstream ifs(f.toFilesystemEncoding().c_str());
218         string nome;
219         dep_info di;
220         // This doesn't change through the loop.
221         di.crc_prev = 0;
222
223         while (ifs >> di.crc_cur >> di.mtime_cur && getline(ifs, nome)) {
224                 nome = ltrim(nome);
225
226                 LYXERR(Debug::DEPEND, "Read dep: "
227                        << di.crc_cur << ' ' << di.mtime_cur << ' ' << nome);
228
229                 deplist[FileName(nome)] = di;
230         }
231         return !deplist.empty();
232 }
233
234
235 } // namespace lyx