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