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