]> git.lyx.org Git - lyx.git/blob - src/vc-backend.C
several small patches
[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 "support/filetools.h"
16 #include "buffer.h"
17 #include "LyXView.h"
18 #include "lyxfunc.h"
19
20 using std::endl;
21 using std::ifstream;
22 using std::getline;
23
24 int VCS::doVCCommand(string const & cmd, string const & path)
25 {
26         lyxerr[Debug::LYXVC] << "doVCCommand: " << cmd << endl;
27         Systemcalls one;
28         Path p(path);
29         int const ret = one.startscript(Systemcalls::System, cmd);
30         return ret;
31 }
32
33
34 RCS::RCS(string const & m)
35 {
36         master_ = m;
37         scanMaster();
38 }
39
40
41 string const RCS::find_file(string const & file)
42 {
43         string tmp(file);
44         // Check if *,v exists.
45         tmp += ",v";
46         FileInfo f;
47         lyxerr[Debug::LYXVC] << "Checking if file is under rcs: "
48                              << tmp << endl;
49         if (f.newFile(tmp).readable()) {
50                 lyxerr[Debug::LYXVC] << "Yes " << file
51                                      << " is under rcs." << endl;
52                 return tmp;
53         } else {
54                 // Check if RCS/*,v exists.
55                 tmp = AddName(AddPath(OnlyPath(file), "RCS"), file);
56                 tmp += ",v";
57                 lyxerr[Debug::LYXVC] << "Checking if file is under rcs: "
58                                      << tmp << endl;
59                 if (f.newFile(tmp).readable()) {
60                         lyxerr[Debug::LYXVC] << "Yes " << file
61                                              << " it is under rcs."<< endl;
62                         return tmp;
63                 }
64         }
65         return string();
66 }
67
68
69 void RCS::retrive(string const & file)
70 {
71         lyxerr[Debug::LYXVC] << "LyXVC::RCS: retrive.\n\t" << file << endl;
72         VCS::doVCCommand("co -q -r \""
73                          + file + "\"",
74                          string());
75 }
76
77
78 void RCS::scanMaster()
79 {
80         lyxerr[Debug::LYXVC] << "LyXVC::RCS: scanMaster." << endl;
81
82         ifstream ifs(master_.c_str());
83
84         string token;
85         bool read_enough = false;
86
87         while (!read_enough && ifs >> token) {
88                 lyxerr[Debug::LYXVC]
89                         << "LyXVC::scanMaster: current lex text: `"
90                         << token << "'" << endl;
91
92                 if (token.empty())
93                         continue;
94                 else if (token == "head") {
95                         // get version here
96                         string tmv;
97                         ifs >> tmv;
98                         tmv = strip(tmv, ';');
99                         version_ = tmv;
100                         lyxerr[Debug::LYXVC] << "LyXVC: version found to be "
101                                              << tmv << endl;
102                 } else if (contains(token, "access")
103                            || contains(token, "symbols")
104                            || contains(token, "strict")) {
105                         // nothing
106                 } else if (contains(token, "locks")) {
107                         // get locker here
108                         if (contains(token, ";")) {
109                                 locker_ = "Unlocked";
110                                 vcstatus = UNLOCKED;
111                                 continue;
112                         }
113                         string tmpt, s1, s2;
114                         do {
115                                 ifs >> tmpt;
116                                 s1 = strip(tmpt, ';');
117                                 // tmp is now in the format <user>:<version>
118                                 s1 = split(s1, s2, ':');
119                                 // s2 is user, and s1 is version
120                                 if (s1 == version_) {
121                                         locker_ = s2;
122                                         vcstatus = LOCKED;
123                                         break;
124                                 }
125                         } while (!contains(tmpt, ";"));
126                         
127                 } else if (token == "comment") {
128                         // we don't need to read any further than this.
129                         read_enough = true;
130                 } else {
131                         // unexpected
132                         lyxerr[Debug::LYXVC]
133                                 << "LyXVC::scanMaster(): unexpected token"
134                                 << endl;
135                 }
136         }
137         version_ = "RCS: " + version_;
138 }
139
140
141 void RCS::registrer(string const & msg)
142 {
143         string cmd = "ci -q -u -i -t-\"";
144         cmd += msg;
145         cmd += "\" \"";
146         cmd += OnlyFilename(owner_->fileName());
147         cmd += "\"";
148         doVCCommand(cmd, owner_->filepath);
149         owner_->getUser()->owner()->getLyXFunc()->Dispatch("buffer-reload");
150 }
151
152
153 void RCS::checkIn(string const & msg)
154 {
155         doVCCommand("ci -q -u -m\"" + msg + "\" \""
156                     + OnlyFilename(owner_->fileName()) + "\"", owner_->filepath);
157         owner_->getUser()->owner()->getLyXFunc()->Dispatch("buffer-reload");
158 }
159
160
161 void RCS::checkOut()
162 {
163         owner_->markLyxClean();
164         doVCCommand("co -q -l \""
165                     + OnlyFilename(owner_->fileName()) + "\"", owner_->filepath);
166         owner_->getUser()->owner()->getLyXFunc()->Dispatch("buffer-reload");
167 }
168
169
170 void RCS::revert()
171 {
172         doVCCommand("co -f -u" + version() + " \""
173                     + OnlyFilename(owner_->fileName()) + "\"", owner_->filepath);
174         // We ignore changes and just reload!
175         owner_->markLyxClean();
176         owner_->getUser()->owner()
177                 ->getLyXFunc()->Dispatch("buffer-reload");
178 }
179
180
181 void RCS::undoLast()
182 {
183         lyxerr[Debug::LYXVC] << "LyXVC: undoLast" << endl;
184         doVCCommand("rcs -o" + version() + " \""
185                     + OnlyFilename(owner_->fileName()) + "\"", owner_->filepath);
186 }
187
188
189 void RCS::getLog(string const & tmpf)
190 {
191         doVCCommand("rlog \""
192                     + OnlyFilename(owner_->fileName()) + "\" > " + tmpf, owner_->filepath);
193 }
194
195
196 CVS::CVS(string const & m, string const & f)
197 {
198         master_ = m;
199         file_ = f;
200         scanMaster();
201 }
202
203
204 string const CVS::find_file(string const & file)
205 {
206         // First we look for the CVS/Entries in the same dir
207         // where we have file.
208         string const dir = OnlyPath(file) + "/CVS/Entries";
209         string const tmpf = "/" + OnlyFilename(file) + "/";
210         lyxerr[Debug::LYXVC] << "LyXVC: checking in `" << dir
211                              << "' for `" << tmpf << "'" << endl;
212         FileInfo const 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 }