#/usr/bin/perl $DATA = '/data'; chop($Date = `date`); format TOP = Camel's Breath Software @<<<<<<<<<<<<<<<<<<<<<<<<<<<<@||| @>>>>>>>>>>>>>>>>>>>>>>>>>>>> $Product, $%, $Date Flea# Date Disposition Subject Reported by Priority Assigned to Phone & Address Description --------------------------------------------------------------- . format RECORD = @>>>> @||||||| @<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< $Bug, $rdate, $disp, $subject @<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<< @<<<<<<<<<<<<<<<<< $reporter, $prior, $assigned ~ @<<<<<<<<<<<<<<<<<<<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< $phone, $description ~ @<<<<<<<<<<<<<<<<<<<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< shift(@addr), $description ~ @<<<<<<<<<<<<<<<<<<<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< shift(@addr), $description ~ @<<<<<<<<<<<<<<<<<<<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< shift(@addr), $description ~ @<<<<<<<<<<<<<<<<<<<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< shift(@addr), $description ~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< $description ~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< $description ~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<... $description . # One summary record is printed for each product. format SUMMARY = ------------------------- Summary for @<<<<<<<<<<<<<<<<<<<<<<<<<<< $Product Fixed = @<<< Rej = @<<< Hi = @<<< Med = @<<< Lo = @<<< $Xfix, $Xrej, $Xhigh, $Xmed, $Xlow . sub numerically { $a <=> $b; } $^ = 'TOP'; # Set top-of-form format. chdir $DATA || die "Can't cd to $DATA: $!\n"; # Now we're ready to begin. Scan our list of products. PROD: foreach $Productdir (<*>) { reset 'X'; # Zero out accumulators chdir "$DATA/$Productdir" || do { warn "Can't cd to $Productdir: $!\n"; next PROD; }; if (open(NAME, '.prodname')) { chop($Product = ); close NAME; } else { ($Product = $Productdir) =~ tr/_/ /; } opendir(DIR, '.') || do { warn "Can't read $Product: $!\n"; next PROD; }; @Buglist = sort numerically grep(/^\d+$/, readdir(DIR)); closedir(DIR); $~ = 'RECORD'; # Set format for normal records. # Now, iterate over the bug report files. BUG: foreach $Bug (@Buglist) { reset 'a-z'; # Clear scratch variables. open(BUGFILE, $Bug) || do { warn "Can't open $Product/$Bug: $!\n"; next BUG; }; LINE: while () { if (/^Address:\s*(.*)/) {@addr = split(/;\s*/, $1);} elsif (/^Assigned-To:\s*(.*)/) {$assigned = $1;} elsif (/^Priority:\s*(.*)/) {$prior = $1;} elsif (/^Phone:\s*(.*)/) {$phone = $1;} elsif (/^Subject:\s*(.*)/) {$subject = $1;} elsif (/^Reported-By:\s*(.*)/) {$reporter = $1;} elsif (/^Disposition:\s*(.*)/) {$disp = $1;} elsif (/^Date-Received:\s*(.*)/) {$rdate = $1;} elsif (/^Description:\s*(.*)/) { $description = $1; DESCLINE: while () { last DESCLINE if /^--/; $description .= $_; } # Make into one long line. $description =~ s/([.!?])\n\s*/$1 /g; $description =~ s/\n\s*/ /g; $description =~ s/^\s*//; } } # Accumulate stats about priorities and dispositions. if ($disp =~ /^open/i) { $prior =~ /^hi/ && $Xhigh++; $prior =~ /^med/ && $Xmed++; $prior =~ /^lo/ && $Xlow++; } elsif ($disp =~ /^fixed/i) { $Xfix++; } elsif ($disp =~ /^rej/i) { $Xrej++; } elsif ($disp =~ /^void/i) { next BUG; } write; # Write one record's worth. } $~ = 'SUMMARY'; # Select summary format. write; # And write one of those. $- = 0; # Force formfeed on next record. chdir $DATA || die "Can't cd back to $DATA: $!\n"; }