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