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