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