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