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