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