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