- Remove the repocopy CSS rule. - Remove another block of text about repocopies. Reviewed by: bugmeister (eadler) Approved by: gabor (mentor)
		
			
				
	
	
		
			538 lines
		
	
	
	
		
			15 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			538 lines
		
	
	
	
		
			15 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable file
		
	
	
	
	
| #!/usr/bin/perl -T
 | |
| # $FreeBSD$
 | |
| 
 | |
| $html_mode     = 1 if $ENV{'DOCUMENT_ROOT'};
 | |
| $self_ref      = $ENV{'SCRIPT_NAME'};
 | |
| ($query_pr_ref = $self_ref) =~ s/-summary//;
 | |
| 
 | |
| $ENV{'PATH'}   = '/bin:/usr/bin:/usr/sbin:/sbin:/usr/local/bin';
 | |
| 
 | |
| $project       = 'FreeBSD';
 | |
| $mail_prefix   = 'freebsd-';
 | |
| $mail_unass    = 'freebsd-bugs';
 | |
| $ports_unass   = 'ports-bugs';
 | |
| $closed_too    = 0;
 | |
| 
 | |
| require './cgi-lib.pl';
 | |
| require './cgi-style.pl';
 | |
| require './query-pr-lib.pl';
 | |
| require 'getopts.pl';
 | |
| 
 | |
| if (!$ENV{'QUERY_STRING'} or $ENV{'QUERY_STRING'} eq 'query') {
 | |
| 	print &html_header("Query $project problem reports");
 | |
| 	&displayform;
 | |
| 	print &html_footer;
 | |
| 	exit(0);
 | |
| }
 | |
| 
 | |
| if ($html_mode) {
 | |
| 	$query_args   = '--restricted ';
 | |
| 	&ReadParse(*input);
 | |
| } else {
 | |
| 	&Getopts('CcqRr:s:T:');
 | |
| 
 | |
| 	$input{'responsible'}	= 'summary' if $opt_R;
 | |
| 	if ($opt_r) {
 | |
| 		($input{'responsible'})	= ($opt_r =~ m/^(\^?[-_a-zA-Z0-9@.]*\$?)$/);
 | |
| 		die 'Insecure args' if ($input{'responsible'} ne $opt_r)
 | |
| 	}
 | |
| 	if ($opt_s) {
 | |
| 		($input{'state'})	= ($opt_s =~ m/^([a-zA-Z]*)$/);
 | |
| 		die 'Insecure args' if ($input{'state'} ne $opt_s)
 | |
| 	}
 | |
| 	$input{'quiet'}		= 'yes' if $opt_q;
 | |
| 	if ($opt_C) {
 | |
| 		$query_args   = '--confidential=yes ';
 | |
| 	} elsif (!$opt_c) {
 | |
| 		$query_args   = '--restricted ';
 | |
| 	}
 | |
| 	if ($opt_T) {
 | |
| 		($tag)	= ($opt_T =~ m/^(\^?[-_a-zA-Z0-9@.]*\$?)$/);
 | |
| 		die 'Insecure args' if ($tag ne $opt_T);
 | |
| 		$input{'text'} = '\[' . $tag . '\]';
 | |
| 	}
 | |
| }
 | |
| 
 | |
| $closed_too = 1 if $input{'state'} eq 'closed' || 
 | |
| 	($input{'closedtoo'} && ($input{'multitext'} || $input{'text'} || $input{'responsible'} || $input{'originator'}));
 | |
| 
 | |
| #------------------------------------------------------------------------
 | |
| 
 | |
| %mons = ('Jan', '01',  'Feb', '02',  'Mar', '03',
 | |
| 	 'Apr', '04',  'May', '05',  'Jun', '06',
 | |
| 	 'Jul', '07',  'Aug', '08',  'Sep', '09',
 | |
| 	 'Oct', '10',  'Nov', '11',  'Dec', '12');
 | |
| 
 | |
| 
 | |
| if ($html_mode) {
 | |
| 
 | |
|     $pr = '<pre>';    $pr_e = '</pre>';
 | |
|     $h1 = '<h1>';     $h1_e = '</h1>';
 | |
|     $h3 = '<h3>';     $h3_e = '</h3>';
 | |
|     $hr = '<hr/>';
 | |
| 
 | |
|     $table   = "<table width='100%' border='0' cellspacing='1' cellpadding='0'>";
 | |
|     $table_e = '</table>';
 | |
| 
 | |
|     # Customizations for the look and feel of the summary tables.
 | |
|     $t_style = "<style type='text/css'><!--\n" .
 | |
| 	"table { background-color: #ccc; color: #000; }\n" .
 | |
| 	"tr { padding: 0; }\n" .
 | |
| 	"th { background-color: #cbd2ec; color: #000; padding: 2px;\n" .
 | |
| 	"     text-align: left; font-weight: normal; font-style: italic; }\n" .
 | |
| 	"td { color: #000; padding: 2px; }\n" .
 | |
| 	"td a { text-decoration: none; }\n" .
 | |
| 	".o { background-color: #fff; }\n" .
 | |
| 	".a { background-color: #cffafd; }\n" .
 | |
| 	".f { background-color: #ffc; }\n" .
 | |
| 	".p { background-color: #d1fbd6; }\n" .
 | |
| 	".s { background-color: #fcccd9; }\n" .
 | |
| 	".c { background-color: #c1d5db; }\n" .
 | |
| 	"--></style>";
 | |
| 
 | |
| } else {
 | |
| 
 | |
|     $pr = ''; $pr_e = '';
 | |
|     $h1 = ''; $h1_e = '';
 | |
|     $h3 = ''; $h3_e = '';
 | |
|     $hr = "\n----------------------------------------" .
 | |
| 	    "---------------------------------------\n";
 | |
| 
 | |
|     $table   = '';
 | |
|     $table_e = '';
 | |
| }
 | |
| 
 | |
| sub cgiparam {
 | |
|     local ($result) = @_;
 | |
| 
 | |
|     $result =~ s/[^A-Za-z0-9+.@-]/"%".sprintf("%02X", unpack("C", $&))/ge;
 | |
|     $result;
 | |
| }
 | |
| 
 | |
| sub header_info {
 | |
|     if ($html_mode) {
 | |
| 	print &html_header("Current $project problem reports");
 | |
|     }
 | |
|     else {
 | |
| 	print "Current $project problem reports\n";
 | |
|     }
 | |
|     if (!$input{'quiet'}) {
 | |
|        print "The following is a listing of current problems submitted by $project users. " .
 | |
| 	  'These represent problem reports covering all versions including ' .
 | |
| 	  'experimental development code and obsolete releases. ';
 | |
|        if ($html_mode) {
 | |
| 	  print <<EOM;
 | |
| 
 | |
| <p>
 | |
| Bugs can be in one of several states:
 | |
| </p>
 | |
| <dl>
 | |
| <dt class='o'><strong>o - open</strong></dt>
 | |
| <dd>A problem report has been submitted, no sanity checking
 | |
| performed.</dd>
 | |
| 
 | |
| <dt class='a'><strong>a - analyzed</strong></dt>
 | |
| <dd>The problem is understood and a solution is being sought.</dd>
 | |
| 
 | |
| <dt class='f'><strong>f - feedback</strong></dt>
 | |
| <dd>Further work requires additional information from the originator
 | |
| or the community—possibly confirmation of the effectiveness of a
 | |
| proposed solution.</dd>
 | |
| 
 | |
| <dt class='p'><strong>p - patched</strong></dt>
 | |
| <dd>A patch has been committed, but some issues (MFC and / or
 | |
| confirmation from originator) are still open.</dd>
 | |
| 
 | |
| <dt class='s'><strong>s - suspended</strong></dt>
 | |
| <dd>The problem is not being worked on, due to lack of information or
 | |
| resources.  This is a prime candidate for somebody who is looking for a
 | |
| project to do. If the problem cannot be solved at all, it will be
 | |
| closed, rather than suspended.</dd>
 | |
| 
 | |
| <dt class='c'><strong>c - closed</strong></dt>
 | |
| <dd>A problem report is closed when any changes have been integrated,
 | |
| documented, and tested—or when fixing the problem is abandoned.</dd>
 | |
| </dl>
 | |
| EOM
 | |
| 
 | |
|        } else {
 | |
| 
 | |
| print <<EOM;
 | |
| 
 | |
| Bugs can be in one of several states:
 | |
| 
 | |
| o - open
 | |
| A problem report has been submitted, no sanity checking performed.
 | |
| 
 | |
| a - analyzed
 | |
| The problem is understood and a solution is being sought.
 | |
| 
 | |
| f - feedback
 | |
| Further work requires additional information from the
 | |
|      originator or the community - possibly confirmation of
 | |
|      the effectiveness of a proposed solution.
 | |
| 
 | |
| p - patched
 | |
| A patch has been committed, but some issues (MFC and / or
 | |
|      confirmation from originator) are still open.
 | |
| 
 | |
| s - suspended
 | |
| The problem is not being worked on, due to lack of information
 | |
|      or resources.  This is a prime candidate
 | |
|      for somebody who is looking for a project to do.
 | |
|      If the problem cannot be solved at all,
 | |
|      it will be closed, rather than suspended.
 | |
| 
 | |
| c - closed
 | |
| A problem report is closed when any changes have been integrated,
 | |
|      documented, and tested -- or when fixing the problem is abandoned.
 | |
| EOM
 | |
|        }
 | |
|     }
 | |
| 
 | |
| 	if ($html_mode) {
 | |
| 
 | |
| # These self references are attempts to only change a single variable at a time.
 | |
| # If someone does a multiple-variable query they will probably do weird things.
 | |
| 
 | |
| $self_ref1 = $self_ref . '?';
 | |
| $self_ref1 .= 'sort=' . html_fixline($input{'sort'}) if $input{'sort'};
 | |
| print "<p>You may view summaries by <a href='$self_ref1'>Severity</a>, ";
 | |
| $self_ref1 .= '&' if ($self_ref1 !~/\?$/);
 | |
| print "<a href='${self_ref1}state=summary'>State</a>, ";
 | |
| print "<a href='${self_ref1}category=summary'>Category</a>, or ";
 | |
| print "<a href='${self_ref1}responsible=summary'>Responsible Party</a>.\n";
 | |
| 
 | |
| $self_ref2 = $self_ref . '?';
 | |
| foreach ('category', 'originator', 'priority', 'class', 'responsible',
 | |
| 	'severity', 'state', 'submitter', 'text', 'multitext', 'closedtoo') {
 | |
| 	if ($input{$_}) {
 | |
| 		$self_ref2 .= '&' if ($self_ref2 !~/\?$/);
 | |
| 		$self_ref2 .= $_ . '=' . cgiparam($input{$_});
 | |
| 	}
 | |
| }
 | |
| 
 | |
| print 'You may also sort by ';
 | |
| print "<a href='$self_ref2&sort=lastmod'>Last-Modified</a>, ";
 | |
| print "<a href='$self_ref2&sort=category'>Category</a>, or ";
 | |
| print "<a href='$self_ref2&sort=responsible'>Responsible Party</a>.\n";
 | |
| print "Or <a href='$self_ref?query'>formulate a specific query</a>.\n";
 | |
| 
 | |
| $self_ref3 = $self_ref . '?';
 | |
| foreach ('category', 'originator', 'priority', 'class', 'responsible',
 | |
| 	'severity', 'state', 'submitter', 'text', 'multitext', 'sort') {
 | |
| 	if ($input{$_}) {
 | |
| 		$self_ref3 .= '&' if ($self_ref2 !~/\?$/);
 | |
| 		$self_ref3 .= $_ . '=' . cgiparam($input{$_});
 | |
| 	}
 | |
| }
 | |
| 
 | |
| if ($input{'closedtoo'}) {
 | |
| 	print "<a href='$self_ref3'>Do not show closed reports</a>.";
 | |
| } else {
 | |
| 	print "<a href='$self_ref3&closedtoo=on'>Include closed reports too</a>.";
 | |
| }
 | |
| 
 | |
| print "</p>\n";
 | |
| 
 | |
| 	}
 | |
| }
 | |
| 
 | |
| &header_info;
 | |
| 
 | |
| #Usage: query-pr [-FGhiPRqVx] [-C confidential] [-c category] [-d directory]
 | |
| #       [-e severity] [-m mtext] [-O originator] [-o outfile] [-p priority]
 | |
| #       [-L class] [-r responsible] [-S submitter] [-s state] [-t text]
 | |
| #       [-b date] [-a date] [-B date] [-M date] [-z date] [-Z date]
 | |
| #       [-y synopsis] [-A release] [--full] [--help] [--print-path] [--version]
 | |
| #       [--summary] [--sql] [--skip-closed] [--category=category]
 | |
| #       [--confidential=yes|no] [--directory=directory] [--output=outfile]
 | |
| #       [--originator=name] [--priority=level] [--class=class]
 | |
| #       [--responsible=person] [--release=release] [--restricted]
 | |
| #       [--quarter=quarter] [--keywords=regexp]
 | |
| #       [--required-before=date] [--required-after=date]
 | |
| #       [--arrived-before=date] [--arrived-after=date]
 | |
| #       [--modified-before=date] [--modified-after=date]
 | |
| #       [--closed-before=date] [--closed-after=date]
 | |
| #       [--severity=severity] [--state=state] [--submitter=submitter]
 | |
| #       [--list-categories] [--list-classes] [--list-responsible]
 | |
| #       [--list-states] [--list-submitters] [--list-config]
 | |
| #       [--synopsis=synopsis] [--text=text] [--multitext=mtext] [PR] [PR]...
 | |
| 
 | |
| $query_args .= ' --skip-closed' unless $closed_too;
 | |
| 
 | |
| # Only read the appropriate PR's.
 | |
| foreach ('category', 'originator', 'priority', 'class', 'responsible',
 | |
| 	'release', 'severity', 'state', 'submitter', 'text', 'multitext') {
 | |
| 	if ($input{$_} && $input{$_} ne 'summary') {
 | |
| 		# Check if the arguments provided by user are secure.
 | |
| 		# This is required to be able to run this script in
 | |
| 		# taint mode (perl -T)
 | |
| 		if ($input{$_} =~ /^([-^'\/\[\]\@\s\w.]+)$/) {
 | |
| 			$d = $1;
 | |
| 			$d =~ s/^"(.*)"$/$&/;
 | |
| 			$d =~ s/'/\\'/;
 | |
| 			$query_args .= " --${_}='$d'";
 | |
| 		} else {
 | |
| 			print "Insecure data in ${_}! Ignoring this filter.<br />".
 | |
| 			      "Only alphanumeric characters and ', /, -, [, ], ^, @ are allowed.";
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| &read_gnats($query_args);
 | |
| 
 | |
| if ($input{'sort'} eq 'lastmod') {
 | |
| 	@prs = sort {$lastmod{$b} cmp $lastmod{$a}} @prs;
 | |
| } elsif ($input{'sort'} eq 'category') {
 | |
| 	@prs = sort {($ca,$na)=split(m|/|,$a); ($cb,$nb)=split(m|/|,$b); $ca eq $cb ? $na <=> $nb : $ca cmp $cb} @prs;
 | |
| } elsif ($input{'sort'} eq 'responsible') {
 | |
| 	@prs = sort {$resp{$a} cmp $resp{$b}} @prs;
 | |
| } else {
 | |
| 	$input{'sort'} = 'none';
 | |
| }
 | |
| 
 | |
| if ($#prs < $[) {
 | |
| 	print "${h1}No matches to your query${h1_e}\n";
 | |
| 
 | |
| } elsif ($input{'responsible'} eq 'summary') {
 | |
| 	&resp_summary;
 | |
| 
 | |
| } elsif ($input{'state'} eq 'summary') {
 | |
| 	&state_summary;
 | |
| 
 | |
| } elsif ($input{'category'} eq 'summary') {
 | |
| 	&cat_summary;
 | |
| 
 | |
| } elsif ($input{'severity'} eq '') {
 | |
| 	&severity_summary;
 | |
| 
 | |
| } else {
 | |
| 	&printcnt(&gnats_summary(1, $html_mode));
 | |
| 
 | |
| }
 | |
| 
 | |
| print &html_footer if $html_mode;
 | |
| 
 | |
| exit(0);
 | |
| 
 | |
| #------------------------------------------------------------------------
 | |
| 
 | |
| sub getline {
 | |
|     local($_) = @_;
 | |
|     ($tag,$remainder) = split(/[ \t]+/, $_, 2);
 | |
|     return $remainder;
 | |
| }
 | |
| 
 | |
| sub html_fixline {
 | |
|     local($line) = @_[0];
 | |
| 
 | |
|     $line =~ s/&/&/g;
 | |
|     $line =~ s/</</g;
 | |
|     $line =~ s/>/>/g;
 | |
| 
 | |
|     $line;
 | |
| }
 | |
| 
 | |
| sub printcnt {
 | |
|     local($cnt) = $_[0];
 | |
| 
 | |
|     if ($cnt) {
 | |
| 	printf("%d problem%s total.\n\n", $cnt, $cnt == 1 ? '' : 's');
 | |
|     }
 | |
| }
 | |
| 
 | |
| sub cat_summary {
 | |
|     &get_categories;
 | |
|     foreach (keys %status) {
 | |
| 	s|/\d+||;
 | |
| 	$cat{$_}++;
 | |
|     }
 | |
|     foreach (@categories) {
 | |
| 	next unless $cat{$_};	# skip categories with no bugs.
 | |
| 	print "${h3}Problems in category: $_ ($catdesc{$_})${h3_e}\n";
 | |
| 	if (/^(\w+)/) {
 | |
| 	    &printcnt(&gnats_summary("\$cat eq \"$1\"", $html_mode));
 | |
| 	} else {
 | |
| 	    print "\n??? weird category $_\n";
 | |
| 	}
 | |
|     }
 | |
| }
 | |
| 
 | |
| sub resp_query {
 | |
|     local($resp) = @_[0];
 | |
|     local($cnt);
 | |
| 
 | |
|     $cnt = &gnats_summary("\$resp eq \"$resp\"", $html_mode);
 | |
|     print "${hr}${b}No problem reports assigned to $resp${b_e}\n"
 | |
| 	if (!$input{"quiet"} && $cnt == 0);
 | |
| }
 | |
| 
 | |
| sub resp_summary {
 | |
|     local($who, %who);
 | |
| 
 | |
|     foreach (keys %resp) {
 | |
| 	$who{$resp{$_}}++;
 | |
|     }
 | |
|     foreach $who (sort keys %who) {
 | |
| 	$cnt = &gnats_summary("\$resp eq \"$who\"", $html_mode);
 | |
|     }
 | |
| }
 | |
| 
 | |
| sub state_summary {
 | |
|     &get_states;
 | |
|     foreach (@states) {
 | |
| 	next if ($_ eq "closed" && !$input{"closedtoo"});
 | |
| 	print "${h3}Problems in state: $_${h3_e}\n";
 | |
| 	if (/^(\w)/) {
 | |
| 	    &printcnt(&gnats_summary("\$state eq \"$1\" ", $html_mode));
 | |
| 	} else {
 | |
| 	    print "\n??? bad state $state\n";
 | |
| 	}
 | |
|     }
 | |
| }
 | |
| 
 | |
| sub severity_summary {
 | |
|     print "${h3}Critical problems${h3_e}\n";
 | |
|     &printcnt(&gnats_summary('$severity eq "critical"', $html_mode));
 | |
| 
 | |
|     print "${h3}Serious problems${h3_e}\n";
 | |
|     &printcnt(&gnats_summary('$severity eq "serious"', $html_mode));
 | |
| 
 | |
|     print "${h3}Non-critical problems${h3_e}\n";
 | |
|     &printcnt(&gnats_summary('$severity eq "non-critical"', $html_mode));
 | |
| }
 | |
| 
 | |
| sub read_gnats {
 | |
|     local($report)   = @_[0];
 | |
| 
 | |
|     open(Q, "query-pr.web $report 2>/dev/null |") || die "Cannot query the PR's\n";
 | |
| 
 | |
|     while(<Q>) {
 | |
| 	chop;
 | |
| 	if(/^>Number:/) {
 | |
| 	    $number = &getline($_);
 | |
| 
 | |
| 	} elsif (/Arrival-Date:/) {
 | |
| 	    $date = &getline($_);
 | |
| 	    # strip timezone if any (between HH:MM:SS and YYYY at end of line):
 | |
| 	    $date =~ s/(\d\d:\d\d:\d\d)\D+(\d{4})$/\1 \2/;
 | |
| 	    ($dow,$mon,$day,$time,$year,$xtra) = split(/[ \t]+/, $date);
 | |
| 	    $day = "0$day" if $day =~ /^[0-9]$/;
 | |
| 	    $date = "$year/$mons{$mon}/$day";
 | |
| 
 | |
| 	} elsif (/>Last-Modified:/) {
 | |
| 	    $lastmod = &getline($_);
 | |
| 	    if ($lastmod =~ /^[ 	]*$/) {	
 | |
| 		$lastmod = $date;
 | |
| 	    } else {
 | |
| 	        # strip timezone if any (between HH:MM:SS and YYYY at end of line):
 | |
| 		$lastmod =~ s/(\d\d:\d\d:\d\d)\D+(\d{4})$/\1 \2/;
 | |
| 		($dow,$mon,$day,$time,$year,$xtra) = split(/[ \t]+/, $lastmod);
 | |
| 		$day = "0$day" if $day =~ /^[0-9]$/;
 | |
| 	        $lastmod = "$year/$mons{$mon}/$day";
 | |
| 	    }
 | |
| 
 | |
| 	} elsif (/>Category:/) {
 | |
| 	    $cat = &getline($_);
 | |
| 
 | |
| 	} elsif (/>Severity:/) {
 | |
| 	    $sev = &getline($_);
 | |
| 
 | |
| 	} elsif (/>Responsible:/) {
 | |
| 	    $resp = &getline($_);
 | |
| 	    $resp =~ s/@.*//;
 | |
| 	    $resp =~ tr/A-Z/a-z/;
 | |
| 	    $resp = "" if (($resp =~ /$mail_unass/o) or ($resp =~ /$ports_unass/o));
 | |
| 	    $resp =~ s/^$mail_prefix//;
 | |
| 
 | |
| 	} elsif (/>State:/) {
 | |
| 	    $status = &getline($_);
 | |
| 	    $status =~ s/(.).*/\1/;
 | |
| 
 | |
| 	} elsif (/>Synopsis:/) {
 | |
| 	    $syn = &getline($_);
 | |
| 	    $syn =~ s/[\t]+/ /g;
 | |
| 
 | |
| 	} elsif (/^$/) {
 | |
| 	    $_ = sprintf("%s/%s", $cat, $number);
 | |
| 
 | |
| 	    $status{$_} = $status;
 | |
| 	    $date{$_} = $date;
 | |
| 	    $resp{$_} = $resp;
 | |
| 	    $syn{$_} = $syn;
 | |
| 	    $sev{$_} = $sev;
 | |
| 	    $lastmod{$_} = $lastmod;
 | |
| 	    push(@prs,$_);
 | |
| 	}
 | |
|     }
 | |
|     close(Q);
 | |
| }
 | |
| 
 | |
| sub gnats_summary {
 | |
|     local($report)   = @_[0];
 | |
|     local($htmlmode) = @_[1];
 | |
|     local($counter)  = 0;
 | |
| 
 | |
|     foreach (@prs) {
 | |
| 	$state = $status{$_};
 | |
| 	$date = $date{$_};
 | |
| 	$resp = $resp{$_};
 | |
| 	$syn = $syn{$_};
 | |
| 	$severity = $sev{$_};
 | |
| 	($cat, $number) = m|^([^/]+)/(\d+)$|;
 | |
| 
 | |
| 	next if (($report ne '') && (eval($report) == 0));
 | |
| 
 | |
| 	if ($htmlmode) {
 | |
| 	    $title = "<a href='$query_pr_ref?pr=$cat/$number'>$_</a>";
 | |
| 	    $syn = &html_fixline($syn);
 | |
| 	    gnats_summary_line_html($counter, $state, $date, $title, $resp, $syn);
 | |
| 	} else {
 | |
| 	    $title = $_;
 | |
| 	    gnats_summary_line_text($counter, $state, $date, $title, $resp, $syn);
 | |
| 	}
 | |
| 
 | |
| 	$counter++;
 | |
|     }
 | |
| 
 | |
|     if ($htmlmode) {
 | |
| 	print "${table_e}\n" if $counter;
 | |
|     } else {
 | |
| 	print "${pr_e}\n" if $counter;
 | |
|     }
 | |
| 
 | |
|     $counter;
 | |
| }
 | |
| 
 | |
| sub gnats_summary_line_html {
 | |
|     local($counter)  = shift;
 | |
|     local($state)    = shift;
 | |
|     local($date)     = shift;
 | |
|     local($title)    = shift;
 | |
|     local($resp)     = shift;
 | |
|     local($syn)      = shift;
 | |
| 
 | |
|     if ($counter == 0) {
 | |
|        print "$table<tr><th>S</th><th>Submitted</th><th>Tracker</th><th>Resp.</th><th>Description</th></tr>\n"
 | |
|     }
 | |
| 
 | |
|     print "<tr class='$state'><td>$state</td><td>$date</td><td>$title</td><td>$resp</td><td>$syn</td></tr>\n";
 | |
| }
 | |
| 
 | |
| sub gnats_summary_line_text {
 | |
|     local($counter)  = shift;
 | |
|     local($state)    = shift;
 | |
|     local($date)     = shift;
 | |
|     local($title)    = shift;
 | |
|     local($resp)     = shift;
 | |
|     local($syn)      = shift;
 | |
| 
 | |
|     # Print the banner line if this is the first iteration.
 | |
|     print "${pr}\nS Submitted  Tracker          Resp.     Description${hr}"
 | |
| 	if ($counter == 0);
 | |
|     print "$state $date $title" .
 | |
| 	(' ' x (17 - length($_))) .
 | |
| 	$resp . (' ' x (10 - length($resp))) .
 | |
| 	substr($syn,0,39) . "\n";
 | |
| }
 |