]> git.lyx.org Git - lyx.git/blob - src/vc-backend.C
rename VCS::stat() to CVS::status()
[lyx.git] / src / vc-backend.C
1 #include <config.h>
2
3 #ifdef __GNUG__
4 #pragma implementation
5 #endif
6
7 #include <fstream>
8
9 #include "vc-backend.h"
10 #include "debug.h"
11 #include "support/FileInfo.h"
12 #include "support/LRegex.h"
13 #include "support/LSubstring.h"
14 #include "support/path.h"
15 #include "buffer.h"
16 #include "LyXView.h"
17 #include "lyxfunc.h"
18
19 using std::endl;
20 using std::ifstream;
21 using std::getline;
22
23 int VCS::doVCCommand(string const & cmd, string const & path)
24 {
25         lyxerr[Debug::LYXVC] << "doVCCommand: " << cmd << endl;
26         Systemcalls one;
27         Path p(path);
28         int ret = one.startscript(Systemcalls::System, cmd);
29         return ret;
30 }
31
32
33 RCS::RCS(string const & m)
34 {
35         master_ = m;
36         scanMaster();
37 }
38
39
40 string RCS::find_file(string const & file)
41 {
42         string tmp(file);
43         // Check if *,v exists.
44         tmp += ",v";
45         FileInfo f;
46         lyxerr[Debug::LYXVC] << "Checking if file is under rcs: "
47                              << tmp << endl;
48         if (f.newFile(tmp).readable()) {
49                 lyxerr[Debug::LYXVC] << "Yes " << file
50                                      << " is under rcs." << endl;
51                 return tmp;
52         } else {
53                 // Check if RCS/*,v exists.
54                 tmp = AddName(AddPath(OnlyPath(file), "RCS"), file);
55                 tmp += ",v";
56                 lyxerr[Debug::LYXVC] << "Checking if file is under rcs: "
57                                      << tmp << endl;
58                 if (f.newFile(tmp).readable()) {
59                         lyxerr[Debug::LYXVC] << "Yes " << file
60                                              << " it is under rcs."<< endl;
61                         return tmp;
62                 }
63         }
64         return string();
65 }
66
67
68 void RCS::retrive(string const & file)
69 {
70         lyxerr[Debug::LYXVC] << "LyXVC::RCS: retrive.\n\t" << file << endl;
71         VCS::doVCCommand("co -q -r \""
72                          + file + "\"",
73                          string());
74 }
75
76
77 void RCS::scanMaster()
78 {
79         lyxerr[Debug::LYXVC] << "LyXVC::RCS: scanMaster." << endl;
80
81         ifstream ifs(master_.c_str());
82
83         string token;
84         bool read_enough = false;
85
86         while (!read_enough && ifs >> token) {
87                 lyxerr[Debug::LYXVC]
88                         << "LyXVC::scanMaster: current lex text: `"
89                         << token << "'" << endl;
90
91                 if (token.empty())
92                         continue;
93                 else if (token == "head") {
94                         // get version here
95                         string tmv;
96                         ifs >> tmv;
97                         tmv = strip(tmv, ';');
98                         version_ = tmv;
99                         lyxerr[Debug::LYXVC] << "LyXVC: version found to be "
100                                              << tmv << endl;
101                 } else if (contains(token, "access")
102                            || contains(token, "symbols")
103                            || contains(token, "strict")) {
104                         // nothing
105                 } else if (contains(token, "locks")) {
106                         // get locker here
107                         if (contains(token, ";")) {
108                                 locker_ = "Unlocked";
109                                 vcstatus = UNLOCKED;
110                                 continue;
111                         }
112                         string tmpt, s1, s2;
113                         do {
114                                 ifs >> tmpt;
115                                 s1 = strip(tmpt, ';');
116                                 // tmp is now in the format <user>:<version>
117                                 s1 = split(s1, s2, ':');
118                                 // s2 is user, and s1 is version
119                                 if (s1 == version_) {
120                                         locker_ = s2;
121                                         vcstatus = LOCKED;
122                                         break;
123                                 }
124                         } while (!contains(tmpt, ";"));
125                         
126                 } else if (token == "comment") {
127                         // we don't need to read any further than this.
128                         read_enough = true;
129                 } else {
130                         // unexpected
131                         lyxerr[Debug::LYXVC]
132                                 << "LyXVC::scanMaster(): unexpected token"
133                                 << endl;
134                 }
135         }
136         version_ = "RCS: " + version_;
137 }
138
139
140 void RCS::registrer(string const & msg)
141 {
142         string cmd = "ci -q -u -i -t-\"";
143         cmd += msg;
144         cmd += "\" \"";
145         cmd += OnlyFilename(owner_->fileName());
146         cmd += "\"";
147         doVCCommand(cmd, owner_->filepath);
148         owner_->getUser()->owner()->getLyXFunc()->Dispatch("buffer-reload");
149 }
150
151
152 void RCS::checkIn(string const & msg)
153 {
154         doVCCommand("ci -q -u -m\"" + msg + "\" \""
155                     + OnlyFilename(owner_->fileName()) + "\"", owner_->filepath);
156         owner_->getUser()->owner()->getLyXFunc()->Dispatch("buffer-reload");
157 }
158
159
160 void RCS::checkOut()
161 {
162         owner_->markLyxClean();
163         doVCCommand("co -q -l \""
164                     + OnlyFilename(owner_->fileName()) + "\"", owner_->filepath);
165         owner_->getUser()->owner()->getLyXFunc()->Dispatch("buffer-reload");
166 }
167
168
169 void RCS::revert()
170 {
171         doVCCommand("co -f -u" + version() + " \""
172                     + OnlyFilename(owner_->fileName()) + "\"", owner_->filepath);
173         // We ignore changes and just reload!
174         owner_->markLyxClean();
175         owner_->getUser()->owner()
176                 ->getLyXFunc()->Dispatch("buffer-reload");
177 }
178
179
180 void RCS::undoLast()
181 {
182         lyxerr[Debug::LYXVC] << "LyXVC: undoLast" << endl;
183         doVCCommand("rcs -o" + version() + " \""
184                     + OnlyFilename(owner_->fileName()) + "\"", owner_->filepath);
185 }
186
187
188 void RCS::getLog(string const & tmpf)
189 {
190         doVCCommand("rlog \""
191                     + OnlyFilename(owner_->fileName()) + "\" > " + tmpf, owner_->filepath);
192 }
193
194
195 CVS::CVS(string const & m, string const & f)
196 {
197         master_ = m;
198         file_ = f;
199         scanMaster();
200 }
201
202
203 string CVS::find_file(string const & file)
204 {
205         // First we look for the CVS/Entries in the same dir
206         // where we have file.
207         string dir = OnlyPath(file);
208         string tmpf = "/" + OnlyFilename(file) + "/";
209         dir += "/CVS/Entries";
210         lyxerr[Debug::LYXVC] << "LyXVC: checking in `" << dir
211                              << "' for `" << tmpf << "'" << endl;
212         FileInfo f(dir);
213         if (f.readable()) {
214                 // Ok we are at least in a CVS dir. Parse the CVS/Entries
215                 // and see if we can find this file. We do a fast and
216                 // dirty parse here.
217                 ifstream ifs(dir.c_str());
218                 string line;
219                 while (getline(ifs, line)) {
220                         lyxerr[Debug::LYXVC] << "\tEntries: " << line << endl;
221                         if (contains(line, tmpf)) return dir;
222                 }
223         }
224         return string();
225 }
226
227
228 void CVS::scanMaster()
229 {
230         lyxerr[Debug::LYXVC] << "LyXVC::CVS: scanMaster. \n     Checking: "
231                              << master_ << endl;
232         // Ok now we do the real scan...
233         ifstream ifs(master_.c_str());
234         string tmpf = "/" + OnlyFilename(file_) + "/";
235         lyxerr[Debug::LYXVC] << "\tlooking for `" << tmpf << "'" << endl;
236         string line;
237         LRegex reg("/(.*)/(.*)/(.*)/(.*)/(.*)");
238         while(getline(ifs, line)) {
239                 lyxerr[Debug::LYXVC] << "\t  line: " << line << endl;
240                 if (contains(line, tmpf)) {
241                         // Ok extract the fields.
242                         LRegex::SubMatches const & sm = reg.exec(line);
243                         //sm[0]; // whole matched string
244                         //sm[1]; // filename
245                         version_ = "CVS: ";
246                         version_ += LSubstring(line, sm[2].first,
247                                               sm[2].second);
248                         string file_date = LSubstring(line, sm[3].first,
249                                                       sm[3].second);
250                         //sm[4]; // options
251                         //sm[5]; // tag or tagdate
252                         FileInfo fi(file_);
253                         time_t mod = fi.getModificationTime();
254                         string mod_date = strip(asctime(gmtime(&mod)), '\n');
255                         lyxerr[Debug::LYXVC]
256                                 <<  "Date in Entries: `" << file_date
257                                 << "'\nModification date of file: `"
258                                 << mod_date << "'" << endl;
259                         if (file_date == mod_date) {
260                                 locker_ = "Unlocked";
261                                 vcstatus = UNLOCKED;
262                         } else {
263                                 // Here we should also to some more checking
264                                 // to see if there are conflicts or not.
265                                 locker_ = "Locked";
266                                 vcstatus = LOCKED;
267                         }
268                         break;
269                 }
270         }
271 }
272
273
274 void CVS::registrer(string const & msg)
275 {
276         doVCCommand("cvs -q add -m \"" + msg + "\" \""
277                     + OnlyFilename(owner_->fileName()) + "\"", owner_->filepath);
278         owner_->getUser()->owner()->getLyXFunc()->Dispatch("buffer-reload");
279 }
280
281
282 void CVS::checkIn(string const & msg)
283 {
284         doVCCommand("cvs -q commit -m \"" + msg + "\" \""
285                     + OnlyFilename(owner_->fileName()) + "\"", owner_->filepath);
286         owner_->getUser()->owner()->getLyXFunc()->Dispatch("buffer-reload");
287 }
288
289
290 void CVS::checkOut()
291 {
292         // cvs update or perhaps for cvs this should be a noop
293         lyxerr << "Sorry not implemented." << endl;
294 }
295
296
297 void CVS::revert()
298 {
299         // not sure how to do this...
300         // rm file
301         // cvs update
302         lyxerr << "Sorry not implemented." << endl;
303 }
304
305
306 void CVS::undoLast()
307 {
308         // merge the current with the previous version
309         // in a reverse patch kind of way, so that the
310         // result is to revert the last changes.
311         lyxerr << "Sorry not implemented." << endl;
312 }
313
314
315 void CVS::getLog(string const &)
316 {
317         lyxerr << "Sorry not implemented." << endl;
318 }