source: trunk/lib/Trac.cc @ 302

Last change on this file since 302 was 302, checked in by Jari Häkkinen, 14 years ago

Addresses #187. Removed the bug related diagnsotics output.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 13.5 KB
Line 
1// $Id: Trac.cc 302 2007-05-11 07:10:22Z jari $
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      if (milestone(first, str.end()))
128        continue;
129      if (source(first, str.end()))
130        continue;
131      hs_ << *first;
132      ++first;
133    }
134  }
135
136
137  bool Trac::comment(std::string::const_iterator& first, 
138                     const std::string::const_iterator& last)
139  {
140    if (first==last)
141      return false;
142
143    const std::string::const_iterator first_orig(first);
144    if (match(first, last, Str("comment:ticket:")).empty()){
145      first = first_orig;
146      return false;
147    }
148     
149    std::string ticket = match(first, last, Digit());
150    if (ticket.empty() || first == last || *first != ':') {
151      first = first_orig;
152      return false;
153    }
154    ++first;
155    std::string comment = match(first, last, Digit());
156    if (comment.empty() ) {
157      first = first_orig;
158      return false;
159    }
160    std::string href(Configuration::instance().trac_root()+"ticket/"+ticket+
161                     "#comment:"+comment);
162    std::string str(first_orig, first);
163    hs_.stream() << anchor(href, str); 
164    return true;
165
166
167    const Configuration& conf = Configuration::instance();
168    hs_.stream() << anchor(conf.trac_root()+"ticket/"+ticket+
169                           "#comment:"+comment,
170                           std::string(first_orig, first)); 
171    return true;
172
173  }
174
175
176  bool Trac::milestone(std::string::const_iterator& first, 
177                       const std::string::const_iterator& last)
178  {
179    if (first==last)
180      return false;
181
182    const std::string::const_iterator first_orig(first);
183
184    if (match(first, last, Str("milestone:")).empty()){
185      first = first_orig;
186      return false;
187    }
188
189    const std::string::const_iterator milestone_begin(first);
190
191    // find the last alphanumerical char before next space (or last)
192    for (std::string::const_iterator i(first); i!=last && *i!=' '; ++i)
193      if (isalnum(*i)) 
194        first = i+1;
195
196    std::string milestone(milestone_begin, first);
197    if (milestone.empty()){
198      first = first_orig;
199      return false;
200    }
201
202    const Configuration& conf = Configuration::instance();
203    hs_.stream() << anchor(conf.trac_root()+"milestone/"+milestone,
204                           std::string(first_orig, first)); 
205    return true;
206  }
207
208
209  bool Trac::source(std::string::const_iterator& first, 
210                    const std::string::const_iterator& last)
211  {
212    if (first==last)
213      return false;
214
215    const std::string::const_iterator first_orig(first);
216
217    if (match(first, last, Str("source:")).empty()){
218      first = first_orig;
219      return false;
220    }
221
222    std::string node;
223    std::string rev;
224    std::string line;
225    const std::string::const_iterator node_begin(first);
226
227    node = match(first, last, not2Char('@', ' '));
228    if (!node.empty() && node[0]=='/')
229      node = node.substr(1, node.size()-1); 
230 
231    if (*first == '@'){
232      ++first;
233      rev = match(first, last, Digit());
234      if (*first == '#') {
235        ++first;
236        line = match(first, last, notChar(' '));
237      }
238    }
239
240    const Configuration& conf = Configuration::instance();
241    std::string href(conf.trac_root()+node);
242    if (!rev.empty()) {
243      href += "@"+rev;
244      if (!line.empty())
245        href += "#"+line;
246    }
247    hs_.stream() << anchor(href, std::string(first_orig, first)); 
248    return true;
249  }
250
251
252  bool Trac::ticket(std::string::const_iterator& first, 
253                    const std::string::const_iterator& last)
254  {
255    if (ticket1(first, last))
256      return true;
257    if (ticket2(first, last))
258      return true;
259    return false;
260  }
261
262
263  bool Trac::ticket1(std::string::const_iterator& first, 
264                     const std::string::const_iterator& last)
265  {
266    if (first==last)
267      return false;
268
269    const std::string::const_iterator first_orig(first);
270    if (*first != '#')
271      return false;
272    ++first;
273    std::string ticket = match(first, last, Digit());
274
275    if (ticket.empty()) {
276      first = first_orig;
277      return false;
278    }
279
280    const Configuration& conf = Configuration::instance();
281    hs_.stream() << anchor(conf.trac_root()+"ticket/"+ticket,
282                           std::string(first_orig, first)); 
283    return true;
284  }
285
286
287  bool Trac::ticket2(std::string::const_iterator& first, 
288                     const std::string::const_iterator& last)
289  {
290    if (first==last)
291      return false;
292
293    const std::string::const_iterator first_orig(first);
294
295    if (match(first, last, Str("ticket:")).empty()){
296      first = first_orig;
297      return false;
298    }
299     
300    std::string ticket = match(first, last, Digit());
301
302    const Configuration& conf = Configuration::instance();
303    hs_.stream() << anchor(conf.trac_root()+"ticket/"+ticket,"#"+ticket); 
304    return true;
305  }
306
307
308  bool Trac::diff(std::string::const_iterator& first, 
309                  const std::string::const_iterator& last)
310  {
311    if (diff1(first, last))
312      return true;
313    if (diff3(first, last))
314      return true;
315    if (diff2(first, last))
316      return true;
317    return false;
318  }
319
320
321  bool Trac::diff1(std::string::const_iterator& first, 
322                   const std::string::const_iterator& last)
323  {
324    if (first==last)
325      return false;
326
327    const std::string::const_iterator first_orig(first);
328    if (match(first, last, Str("diff:")).empty()){
329      first = first_orig;
330      return false;
331    }
332    std::string node = match(first, last, notChar('@'));
333    if (first==last){
334      first = first_orig;
335      return false;
336    }
337    ++first; 
338    std::string old_rev = match(first, last, Digit());
339    if (old_rev.empty() || first == last || *first != ':') {
340      first = first_orig;
341      return false;
342    }
343    ++first;
344    std::string new_rev = match(first, last, Digit());
345    if (new_rev.empty() ) {
346      first = first_orig;
347      return false;
348    }
349    std::string href;
350    if (node.empty())
351      href = std::string(Configuration::instance().trac_root()+
352                         "changeset?new="+new_rev+"&old="+old_rev);
353    else
354      href = std::string(Configuration::instance().trac_root()+
355                         "changeset?new="+new_rev+"&new_path="+node+"&old="+
356                         old_rev+"&oldpath="+node);
357    hs_.stream() << anchor(href, std::string(first_orig, first)); 
358    return true;
359  }
360
361
362  bool Trac::diff2(std::string::const_iterator& first, 
363                   const std::string::const_iterator& last)
364  {
365    if (first==last)
366      return false;
367
368    const std::string::const_iterator first_orig(first);
369    if (match(first, last, Str("diff:")).empty()){
370      first = first_orig;
371      return false;
372    }
373    std::string old_path(match(first, last, not2Str("//", " ")));
374    std::string new_path;
375    if (first==last || *first==' ')
376      new_path = old_path;
377    else {
378      first += 2;
379      new_path = match(first, last, notChar(' '));
380    }
381    if (new_path.empty() || old_path.empty()){
382      first = first_orig;
383      return false;
384    }
385    std::string href(Configuration::instance().trac_root()+
386                     "changeset?new_path="+new_path+"&old_path="+old_path);
387    hs_.stream() << anchor(href, std::string(first_orig, first)); 
388    return true;
389  }
390
391
392  bool Trac::diff3(std::string::const_iterator& first, 
393                   const std::string::const_iterator& last)
394  {
395    if (first==last)
396      return false;
397
398    const std::string::const_iterator first_orig(first);
399    if (match(first, last, Str("diff:")).empty()){
400      first = first_orig;
401      return false;
402    }
403    std::string old_path(match(first, last, not2Char('@', ' ')));
404    if (*first!='@'){
405      first = first_orig;
406      return false;
407    }
408    ++first;
409    std::string old_rev(match(first, last, Digit()));
410    if (!match_begin(first, first+1, std::string("//"))) {
411      first = first_orig;
412      return false;
413    }
414    first+2;
415    std::string new_path = match(first, last, not2Char('@', ' '));
416    if (*first!='@'){
417      first = first_orig;
418      return false;
419    }
420    ++first;
421    std::string new_rev(match(first, last, Digit()));
422    if (new_rev.empty()){
423      first = first_orig;
424      return false;
425    }
426   
427    std::string href(Configuration::instance().trac_root()+
428                     "changeset?new="+new_rev+"&new_path="+new_path+
429                     "&old="+old_rev+"&old_path="+old_path);
430    hs_.stream() << anchor(href, std::string(first_orig, first)); 
431    return true;
432  }
433
434
435  bool Trac::log(std::string::const_iterator& first, 
436                 const std::string::const_iterator& last)
437  {
438    if (log1(first, last))
439      return true;
440    if (log2(first, last))
441      return true;
442    if (log3(first, last))
443      return true;
444    return false;
445  }
446
447
448  bool Trac::log1(std::string::const_iterator& first, 
449                     const std::string::const_iterator& last)
450  {
451    if (first==last)
452      return false;
453
454    const std::string::const_iterator first_orig(first);
455    if (*first != 'r')
456      return false;
457    ++first;
458
459    std::string stop_rev = match(first, last, Digit());
460    if (stop_rev.empty() || first == last || *first != ':') {
461      first = first_orig;
462      return false;
463    }
464    ++first;
465    std::string rev = match(first, last, Digit());
466    if (rev.empty() ) {
467      first = first_orig;
468      return false;
469    }
470    std::string href(Configuration::instance().trac_root()+"log/?rev="+
471                     rev+"&stop_rev="+stop_rev);
472    hs_.stream() << anchor(href, std::string(first_orig, first)); 
473    return true;
474  }
475
476
477  bool Trac::log2(std::string::const_iterator& first, 
478                     const std::string::const_iterator& last)
479  {
480    if (first==last)
481      return false;
482
483    const std::string::const_iterator first_orig(first);
484    if (*first != '[')
485      return false;
486    ++first;
487
488    std::string stop_rev = match(first, last, Digit());
489    if (stop_rev.empty() || first == last || *first != ':') {
490      first = first_orig;
491      return false;
492    }
493    ++first;
494    std::string rev = match(first, last, Digit());
495    if (rev.empty() || first == last || *first != ']') {
496      first = first_orig;
497      return false;
498    }
499    std::string href(Configuration::instance().trac_root()+"log/?rev="+
500                     rev+"&stop_rev="+stop_rev);
501    hs_.stream() << anchor(href, std::string(first_orig, first)); 
502    return true;
503  }
504
505
506  bool Trac::log3(std::string::const_iterator& first, 
507                  const std::string::const_iterator& last)
508  {
509    if (first==last)
510      return false;
511
512    const std::string::const_iterator first_orig(first);
513
514    const std::string log_str("log:"); 
515    if (!match_begin(first, last, log_str)) {
516      first = first_orig;
517      return false;
518    }
519    first += log_str.size();
520    std::string node = match(first, last, not2Char('#', '@'));
521    ++first;
522    std::string stop_rev = match(first, last, Digit());
523    if (stop_rev.empty() || first == last || *first != ':') {
524      first = first_orig;
525      return false;
526    }
527    ++first;
528    std::string rev = match(first, last, Digit());
529    if (rev.empty() ) {
530      first = first_orig;
531      return false;
532    }
533    std::string href;
534    if (!node.empty() && node[0]=='/')
535      href = std::string(Configuration::instance().trac_root()+"log"+node+
536                         "?rev="+rev+"&stop_rev="+stop_rev);
537    else
538      href = std::string(Configuration::instance().trac_root()+"log/"+node+
539                         "?rev="+rev+"&stop_rev="+stop_rev);
540     
541    hs_.stream() << anchor(href, std::string(first_orig, first)); 
542    return true;
543  }
544
545}} // end of namespace svndigest and namespace theplu
Note: See TracBrowser for help on using the repository browser.