source: trunk/lib/Trac.cc @ 294

Last change on this file since 294 was 294, checked in by Peter Johansson, 16 years ago

refs #180, support:
diff:@288:294,
diff:tags/release-0.4/bin//tags/release-0.5/bin or
diff:trunk/lib/Trac.cc@288//trunk/lib/Trac.cc@294

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 11.5 KB
Line 
1// $Id: Trac.cc 294 2007-05-08 17:47:12Z peter $
2
3/*
4  Copyright (C) 2007 Peter Johansson
5
6  This file is part of svndigest, http://lev.thep.lu.se/trac/svndigest
7
8  svndigest is free software; you can redistribute it and/or modify it
9  under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 2 of the License, or
11  (at your option) any later version.
12
13  svndigest is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21  02111-1307, USA.
22*/
23
24#include "Trac.h"
25
26#include "Configuration.h"
27#include "HtmlStream.h"
28#include "html_utility.h"
29#include "utility.h"
30
31namespace theplu{
32namespace svndigest{
33
34  Trac::Trac(HtmlStream& hs)
35    : hs_(hs) 
36  {}
37
38  bool Trac::changeset(std::string::const_iterator& first, 
39                       const std::string::const_iterator& last)
40  {
41    if (changeset1(first, last))
42      return true;
43    if (changeset2(first, last))
44      return true;
45    if (changeset3(first, last))
46      return true;
47    return false;
48  }
49
50
51  bool Trac::changeset1(std::string::const_iterator& first, 
52                        const std::string::const_iterator& last)
53  {
54    if (first==last)
55      return false;
56    if (*first != 'r')
57      return false;
58    const std::string::const_iterator first_orig(first);
59    ++first;
60    std::string rev = match(first, last, Digit());
61    if (rev.empty()){
62      first = first_orig;
63      return false;
64    }
65    std::string href(Configuration::instance().trac_root()+"changeset/"+rev);
66    hs_.stream() << anchor(href, std::string(first_orig,first)); 
67    return true;
68  }
69
70
71  bool Trac::changeset2(std::string::const_iterator& first, 
72                        const std::string::const_iterator& last)
73  {
74    if (first==last)
75      return false;
76    if (*first != '[')
77      return false;
78    const std::string::const_iterator first_orig(first);
79    ++first;
80    std::string rev = match(first, last, Digit());
81    if (rev.empty() || first==last || *first!=']'){
82      first = first_orig;
83      return false;
84    }
85    ++first;
86    std::string href(Configuration::instance().trac_root()+"changeset/"+rev);
87    hs_.stream() << anchor(href, std::string(first_orig,first)); 
88    return true;
89  }
90
91
92  bool Trac::changeset3(std::string::const_iterator& first, 
93                        const std::string::const_iterator& last)
94  {
95    if (first==last)
96      return false;
97    const std::string::const_iterator first_orig(first);
98    if (match(first, last, Str("changeset:")).empty()){
99      first = first_orig;
100      return false;
101    }
102    std::string rev = match(first, last, Digit());
103    if (rev.empty()){
104      first = first_orig;
105      return false;
106    }
107    std::string href(Configuration::instance().trac_root()+"changeset/"+rev);
108    hs_.stream() << anchor(href, std::string(first_orig,first)); 
109    return true;
110  }
111
112
113  void Trac::print(std::string str)
114  {
115    std::string::const_iterator first(str.begin());
116    while (first!=str.end()) {
117      if (log(first, str.end()))
118        continue;
119      if (ticket(first, str.end()))
120        continue;
121      if (comment(first, str.end()))
122        continue;
123      if (changeset(first, str.end()))
124        continue;
125      if (diff(first, str.end()))
126        continue;
127      hs_ << *first;
128      ++first;
129    }
130  }
131
132
133  bool Trac::comment(std::string::const_iterator& first, 
134                     const std::string::const_iterator& last)
135  {
136    if (first==last)
137      return false;
138
139    const std::string::const_iterator first_orig(first);
140    if (match(first, last, Str("comment:ticket:")).empty()){
141      first = first_orig;
142      return false;
143    }
144     
145    std::string ticket = match(first, last, Digit());
146    if (ticket.empty() || first == last || *first != ':') {
147      first = first_orig;
148      return false;
149    }
150    ++first;
151    std::string comment = match(first, last, Digit());
152    if (comment.empty() ) {
153      first = first_orig;
154      return false;
155    }
156    std::string href(Configuration::instance().trac_root()+"ticket/"+ticket+
157                     "#comment:"+comment);
158    std::string str(first_orig, first);
159    hs_.stream() << anchor(href, str); 
160    return true;
161
162
163    const Configuration& conf = Configuration::instance();
164    hs_.stream() << anchor(conf.trac_root()+"ticket/"+ticket,"#"+ticket); 
165    return true;
166
167  }
168
169
170  bool Trac::ticket(std::string::const_iterator& first, 
171                    const std::string::const_iterator& last)
172  {
173    if (ticket1(first, last))
174      return true;
175    if (ticket2(first, last))
176      return true;
177    return false;
178  }
179
180
181  bool Trac::ticket1(std::string::const_iterator& first, 
182                     const std::string::const_iterator& last)
183  {
184    if (first==last)
185      return false;
186
187    const std::string::const_iterator first_orig(first);
188    if (*first != '#')
189      return false;
190    ++first;
191    std::string ticket = match(first, last, Digit());
192
193    if (ticket.empty()) {
194      first = first_orig;
195      return false;
196    }
197
198    const Configuration& conf = Configuration::instance();
199    hs_.stream() << anchor(conf.trac_root()+"ticket/"+ticket,"#"+ticket); 
200    return true;
201  }
202
203
204  bool Trac::ticket2(std::string::const_iterator& first, 
205                     const std::string::const_iterator& last)
206  {
207    if (first==last)
208      return false;
209
210    const std::string::const_iterator first_orig(first);
211
212    if (match(first, last, Str("ticket:")).empty()){
213      first = first_orig;
214      return false;
215    }
216     
217    std::string ticket = match(first, last, Digit());
218
219    const Configuration& conf = Configuration::instance();
220    hs_.stream() << anchor(conf.trac_root()+"ticket/"+ticket,"#"+ticket); 
221    return true;
222  }
223
224
225  bool Trac::diff(std::string::const_iterator& first, 
226                  const std::string::const_iterator& last)
227  {
228    if (diff1(first, last))
229      return true;
230    if (diff3(first, last))
231      return true;
232    if (diff2(first, last))
233      return true;
234    return false;
235  }
236
237
238  bool Trac::diff1(std::string::const_iterator& first, 
239                   const std::string::const_iterator& last)
240  {
241    if (first==last)
242      return false;
243
244    const std::string::const_iterator first_orig(first);
245    if (match(first, last, Str("diff:")).empty()){
246      first = first_orig;
247      return false;
248    }
249    std::string node = match(first, last, notChar('@'));
250    if (first==last){
251      first = first_orig;
252      return false;
253    }
254    ++first; 
255    std::string old_rev = match(first, last, Digit());
256    if (old_rev.empty() || first == last || *first != ':') {
257      first = first_orig;
258      return false;
259    }
260    ++first;
261    std::string new_rev = match(first, last, Digit());
262    if (new_rev.empty() ) {
263      first = first_orig;
264      return false;
265    }
266    std::string href;
267    if (node.empty())
268      href = std::string(Configuration::instance().trac_root()+
269                         "changeset?new="+new_rev+"&old="+old_rev);
270    else
271      href = std::string(Configuration::instance().trac_root()+
272                         "changeset?new="+new_rev+"&new_path="+node+"&old="+
273                         old_rev+"&oldpath="+node);
274    hs_.stream() << anchor(href, std::string(first_orig, first)); 
275    return true;
276  }
277
278
279  bool Trac::diff2(std::string::const_iterator& first, 
280                   const std::string::const_iterator& last)
281  {
282    if (first==last)
283      return false;
284
285    const std::string::const_iterator first_orig(first);
286    if (match(first, last, Str("diff:")).empty()){
287      first = first_orig;
288      return false;
289    }
290    std::string old_path(match(first, last, not2Str("//", " ")));
291    std::string new_path;
292    if (first==last || *first==' ')
293      new_path = old_path;
294    else {
295      first += 2;
296      new_path = match(first, last, notChar(' '));
297    }
298    if (new_path.empty() || old_path.empty()){
299      first = first_orig;
300      return false;
301    }
302    std::string href(Configuration::instance().trac_root()+
303                     "changeset?new_path="+new_path+"&old_path="+old_path);
304    hs_.stream() << anchor(href, std::string(first_orig, first)); 
305    return true;
306  }
307
308
309  bool Trac::diff3(std::string::const_iterator& first, 
310                   const std::string::const_iterator& last)
311  {
312    if (first==last)
313      return false;
314
315    const std::string::const_iterator first_orig(first);
316    if (match(first, last, Str("diff:")).empty()){
317      first = first_orig;
318      return false;
319    }
320    std::string old_path(match(first, last, not2Char('@', ' ')));
321    if (*first!='@'){
322      first = first_orig;
323      return false;
324    }
325    ++first;
326    std::string old_rev(match(first, last, Digit()));
327    if (!match_begin(first, first+1, std::string("//"))) {
328      first = first_orig;
329      return false;
330    }
331    first+2;
332    std::string new_path = match(first, last, not2Char('@', ' '));
333    if (*first!='@'){
334      first = first_orig;
335      return false;
336    }
337    ++first;
338    std::string new_rev(match(first, last, Digit()));
339    if (new_rev.empty()){
340      first = first_orig;
341      return false;
342    }
343   
344    std::string href(Configuration::instance().trac_root()+
345                     "changeset?new="+new_rev+"&new_path="+new_path+
346                     "&old="+old_rev+"&old_path="+old_path);
347    hs_.stream() << anchor(href, std::string(first_orig, first)); 
348    return true;
349  }
350
351
352  bool Trac::log(std::string::const_iterator& first, 
353                 const std::string::const_iterator& last)
354  {
355    if (log1(first, last))
356      return true;
357    if (log2(first, last))
358      return true;
359    if (log3(first, last))
360      return true;
361    return false;
362  }
363
364
365  bool Trac::log1(std::string::const_iterator& first, 
366                     const std::string::const_iterator& last)
367  {
368    if (first==last)
369      return false;
370
371    const std::string::const_iterator first_orig(first);
372    if (*first != 'r')
373      return false;
374    ++first;
375
376    std::string stop_rev = match(first, last, Digit());
377    if (stop_rev.empty() || first == last || *first != ':') {
378      first = first_orig;
379      return false;
380    }
381    ++first;
382    std::string rev = match(first, last, Digit());
383    if (rev.empty() ) {
384      first = first_orig;
385      return false;
386    }
387    std::string href(Configuration::instance().trac_root()+"log/?rev="+
388                     rev+"&stop_rev="+stop_rev);
389    hs_.stream() << anchor(href, std::string(first_orig, first)); 
390    return true;
391  }
392
393
394  bool Trac::log2(std::string::const_iterator& first, 
395                     const std::string::const_iterator& last)
396  {
397    if (first==last)
398      return false;
399
400    const std::string::const_iterator first_orig(first);
401    if (*first != '[')
402      return false;
403    ++first;
404
405    std::string stop_rev = match(first, last, Digit());
406    if (stop_rev.empty() || first == last || *first != ':') {
407      first = first_orig;
408      return false;
409    }
410    ++first;
411    std::string rev = match(first, last, Digit());
412    if (rev.empty() || first == last || *first != ']') {
413      first = first_orig;
414      return false;
415    }
416    std::string href(Configuration::instance().trac_root()+"log/?rev="+
417                     rev+"&stop_rev="+stop_rev);
418    hs_.stream() << anchor(href, std::string(first_orig, first)); 
419    return true;
420  }
421
422
423  bool Trac::log3(std::string::const_iterator& first, 
424                  const std::string::const_iterator& last)
425  {
426    if (first==last)
427      return false;
428
429    const std::string::const_iterator first_orig(first);
430
431    const std::string log_str("log:"); 
432    if (!match_begin(first, last, log_str)) {
433      first = first_orig;
434      return false;
435    }
436    first += log_str.size();
437    std::string node = match(first, last, not2Char('#', '@'));
438    ++first;
439    std::string stop_rev = match(first, last, Digit());
440    if (stop_rev.empty() || first == last || *first != ':') {
441      first = first_orig;
442      return false;
443    }
444    ++first;
445    std::string rev = match(first, last, Digit());
446    if (rev.empty() ) {
447      first = first_orig;
448      return false;
449    }
450    std::string href;
451    if (!node.empty() && node[0]=='/')
452      href = std::string(Configuration::instance().trac_root()+"log"+node+
453                         "?rev="+rev+"&stop_rev="+stop_rev);
454    else
455      href = std::string(Configuration::instance().trac_root()+"log/"+node+
456                         "?rev="+rev+"&stop_rev="+stop_rev);
457     
458    hs_.stream() << anchor(href, std::string(first_orig, first)); 
459    return true;
460  }
461
462}} // end of namespace svndigest and namespace theplu
Note: See TracBrowser for help on using the repository browser.