summaryrefslogtreecommitdiffstats
path: root/Bugzilla/PatchReader/DiffPrinter/template.pm
blob: 6545e9336e178fdb3905cad863693acdfe3fa797 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
package Bugzilla::PatchReader::DiffPrinter::template;

use strict;

sub new {
  my $class = shift;
  $class = ref($class) || $class;
  my $this = {};
  bless $this, $class;

  $this->{TEMPLATE_PROCESSOR} = $_[0];
  $this->{HEADER_TEMPLATE} = $_[1];
  $this->{FILE_TEMPLATE} = $_[2];
  $this->{FOOTER_TEMPLATE} = $_[3];
  $this->{ARGS} = $_[4] || {};

  $this->{ARGS}{file_count} = 0;
  return $this;
}

sub start_patch {
  my $this = shift;
  $this->{TEMPLATE_PROCESSOR}->process($this->{HEADER_TEMPLATE}, $this->{ARGS})
      || ::ThrowTemplateError($this->{TEMPLATE_PROCESSOR}->error());
}

sub end_patch {
  my $this = shift;
  $this->{TEMPLATE_PROCESSOR}->process($this->{FOOTER_TEMPLATE}, $this->{ARGS})
      || ::ThrowTemplateError($this->{TEMPLATE_PROCESSOR}->error());
}

sub start_file {
  my $this = shift;
  $this->{ARGS}{file_count}++;
  $this->{ARGS}{file} = shift;
  $this->{ARGS}{file}{plus_lines} = 0;
  $this->{ARGS}{file}{minus_lines} = 0;
  @{$this->{ARGS}{sections}} = ();
}

sub end_file {
  my $this = shift;
  my $file = $this->{ARGS}{file};
  if ($file->{canonical} && $file->{old_revision} && $this->{ARGS}{bonsai_url}) {
    $this->{ARGS}{bonsai_prefix} = "$this->{ARGS}{bonsai_url}/cvsblame.cgi?file=$file->{filename}&rev=$file->{old_revision}";
  }
  if ($file->{canonical} && $this->{ARGS}{lxr_url}) {
    # Cut off the lxr root, if any
    my $filename = $file->{filename};
    $filename = substr($filename, length($this->{ARGS}{lxr_root}));
    $this->{ARGS}{lxr_prefix} = "$this->{ARGS}{lxr_url}/source/$filename";
  }

  $this->{TEMPLATE_PROCESSOR}->process($this->{FILE_TEMPLATE}, $this->{ARGS})
      || ::ThrowTemplateError($this->{TEMPLATE_PROCESSOR}->error());
  @{$this->{ARGS}{sections}} = ();
  delete $this->{ARGS}{file};
}

sub next_section {
  my $this = shift;
  my ($section) = @_;

  $this->{ARGS}{file}{plus_lines} += $section->{plus_lines};
  $this->{ARGS}{file}{minus_lines} += $section->{minus_lines};

  # Get groups of lines and print them
  my $last_line_char = '';
  my $context_lines = [];
  my $plus_lines = [];
  my $minus_lines = [];
  foreach my $line (@{$section->{lines}}) {
    $line =~ s/\r?\n?$//;
    if ($line =~ /^ /) {
      if ($last_line_char ne ' ') {
        push @{$section->{groups}}, {context => $context_lines,
                                     plus => $plus_lines,
                                     minus => $minus_lines};
        $context_lines = [];
        $plus_lines = [];
        $minus_lines = [];
      }
      $last_line_char = ' ';
      push @{$context_lines}, substr($line, 1);
    } elsif ($line =~ /^\+/) {
      if ($last_line_char eq ' ' || $last_line_char eq '-' && @{$plus_lines}) {
        push @{$section->{groups}}, {context => $context_lines,
                                     plus => $plus_lines,
                                     minus => $minus_lines};
        $context_lines = [];
        $plus_lines = [];
        $minus_lines = [];
        $last_line_char = '';
      }
      $last_line_char = '+';
      push @{$plus_lines}, substr($line, 1);
    } elsif ($line =~ /^-/) {
      if ($last_line_char eq '+' && @{$minus_lines}) {
        push @{$section->{groups}}, {context => $context_lines,
                                     plus => $plus_lines,
                                     minus => $minus_lines};
        $context_lines = [];
        $plus_lines = [];
        $minus_lines = [];
        $last_line_char = '';
      }
      $last_line_char = '-';
      push @{$minus_lines}, substr($line, 1);
    }
  }

  push @{$section->{groups}}, {context => $context_lines,
                               plus => $plus_lines,
                               minus => $minus_lines};
  push @{$this->{ARGS}{sections}}, $section;
}

1