#! /usr/local/bin/perl -w # # changelog2graph - a tool to graph ChangeLog file. # # Usage: # # % changelog2graph ChangeLog > ChangeLog.png # # Copyright (C) 2000 Satoru Takabayashi # All rights reserved. # This is free software with ABSOLUTELY NO WARRANTY. # # You can redistribute it and/or modify it under the terms of # the GNU General Public License version 2. # use strict; use Chart::PNGgraph::lines; use Time::Local; use constant Independent => 0; use constant Cumulative => 1; my %month_names = ("Jan" => 0, "Feb" => 1, "Mar" => 2, "Apr" => 3, "May" => 4, "Jun" => 5, "Jul" => 6, "Aug" => 7, "Sep" => 8, "Oct" => 9, "Nov" => 10, "Dec" => 11); main(); sub main { my %freqs = analyze_changelog(); my $first_time = get_first_time(\%freqs); my $last_time = get_last_time(\%freqs); my @data = generate_data(\%freqs, $first_time, $last_time); my $my_graph = new Chart::PNGgraph::lines(600,400); $my_graph->set( transparent => 0, two_axes => 1, line_width => 2, x_label => 'Date', y_label => 'Changes', title => 'ChangeLog Graph', x_label_skip => int(@{$data[0]} / 8) + 1, y_label_skip => 2, r_margin => 20, textclr => "black", dclrs => [ qw(red blue green pink cyan) ], ); print $my_graph->plot(\@data); } sub analyze_changelog () { my %freqs = (); my $date = undef; my $freq = 0; while (<>) { next if /^\s*$/; chomp; if (/^(?:Sun|Mon|Tue|Wed|Thu|Fri|Sat)\s+ (\w+)\s+(\d+)\s+(?:[\d:]+)\s+(\d+)(.*)/x) { # Old type format: # Wed Jun 2 17:55:44 1999 Foo Bar my $mon = $month_names{$1} + 1; my $mday = $2; my $year = $3; my $rest = $4; # Convert it to ISO 8601 type. $_ = sprintf "%4d-%02d-%02d%s", $year, $mon, $mday, $rest; } if (/^(\d{4}-\d{2}-\d{2})\s/) { # ISO 8601 format: # 1999-06-02 Foo Bar if (defined $date) { $freqs{$date} = $freq; } $date = $1; $freq = 0; } elsif (/^\s+\*/) { $freq++; } } $freqs{$date} = $freq; return %freqs; } sub get_first_time ($) { my ($freqs_ref) = @_; my $first_date = (sort keys %{$freqs_ref})[0]; return date_to_time($first_date); } sub get_last_time ($) { my ($freqs_ref) = @_; my $last_date = (reverse sort keys %{$freqs_ref})[0]; return date_to_time($last_date); } sub date_to_time ($) { my ($date) = @_; if ($date =~ /^(\d+)-(\d+)-(\d+)/) { my $year = $1; my $mon = $2 - 1; my $mday = $3; return timelocal(0, 0, 0, $mday, $mon, $year); } else { die "$date: invalid date format"; } } sub generate_data ($$$) { my ($freqs_ref, $first_time, $last_time) = @_; my @dates = (); my @indps = (); # independent my @cumls = (); # cumulative my $sum = 0; for (my $time = $first_time; $time <= $last_time; $time += 60 * 60 * 24) { my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime($time); $year += 1900; $mon++; my $date = sprintf "%4d-%02d-%02d", $year, $mon, $mday; push @dates, $date; if (defined $freqs_ref->{$date}) { push @indps, $freqs_ref->{$date}; $sum += $freqs_ref->{$date} } else { push @indps, 0; } push @cumls, $sum; } return ([ @dates ], [ @indps ], [ @cumls ]); }