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