summaryrefslogtreecommitdiff
path: root/dist/extractnews
diff options
context:
space:
mode:
Diffstat (limited to 'dist/extractnews')
-rwxr-xr-xdist/extractnews183
1 files changed, 183 insertions, 0 deletions
diff --git a/dist/extractnews b/dist/extractnews
new file mode 100755
index 0000000..bce94c9
--- /dev/null
+++ b/dist/extractnews
@@ -0,0 +1,183 @@
+#!/usr/bin/perl
+
+use strict;
+use Text::Wrap;
+my %output;
+my $text;
+my %stash;
+
+use Getopt::Long;
+
+my %opts = (
+ c => 'CHANGES.new',
+ n => 'NEWS.new',
+ );
+
+LocalGetOptions(\%opts,
+ ['s|start-regexp=s','A regexp to look for in files to start converting at'],
+ ['e|end-regexp=s','A regexp to look for in files to end converting at'],
+ "",
+ ['c|changes-file=s','A file to save CHANGES entries to'],
+ ['n|news-file=s','A file to save NEWS entries to'],
+ ['d|debug-line=s', 'Debugging output for lines matching STRING'],
+ "",
+ ['GUI:otherargs_text','Input files to parse'],
+ );
+
+my $maybecontinue = 0;
+my $lasttext = "";
+my $lastfile;
+my $lastcomponent;
+
+foreach my $argv (@ARGV) {
+ open(I, $argv);
+ if ($opts{'s'}) {
+ while (<I>) {
+ last if (/$opts{'s'}/o);
+ }
+ }
+
+ while (<I>) {
+ my ($file, $component, $patbug, $nums, $text);
+
+ last if ($opts{'e'} && /$opts{e}/o);
+
+ print STDERR "here: $_" if ($opts{'d'} && /$opts{'d'}/o);
+
+ # don't use this:
+ # FILE: BUGS: 123,456: text
+ ($file, $patbug, $nums, $text) =
+ /(NEWS|CHANGES):\s*-*\s*\[*(BUG|PATCH)(?:ES|S|):*\s*([\d,\s*]*)\]*:*\s*-*\s*(.*)/;
+
+ print STDERR " 1:$file, $component, $patbug, $nums, $text\n" if ($opts{'d'} && /$opts{'d'}/o);
+
+ # or this:
+ # FILE: component - text
+ ($file, $component, $text) =
+ /(NEWS|CHANGES):\s*(\w+)\s*-+\s*(.*)/ if (!$file);
+
+ print STDERR " 2:$file, $component, $patbug, $nums, $text\n" if ($opts{'d'} && /$opts{'d'}/o);
+
+ # what you should use:
+ # FILE: component: BUGS: 123,456: text
+ #
+ # or
+ # FILE: component: PATCH: 123,456: from someone text
+ # FILE: component: PATCH: 123,456: from "someone long" text
+ ($file, $component, $patbug, $nums, $text) =
+ /(NEWS|CHANGES):\s*([^:]+):\s*-*\s*\[*(BUG|PATCH)(?:ES|S):*\s*([\d,\s*]*)\]*:*\s*-*\s*(?:from ["'][^"]+["']|from \w+|):*\s*(.*)/ if (!$file);
+
+ print STDERR " 3:$file, $component, $patbug, $nums, $text\n" if ($opts{'d'} && /$opts{'d'}/o);
+
+ # or at least:
+ # FILE: component: text
+ ($file, $component, $text) =
+ /(NEWS|CHANGES):\s*([^:]+):\s*-*\s*(.*)/ if (!$file);
+
+ print STDERR " 4:$file, $component, $patbug, $nums, $text\n" if ($opts{'d'} && /$opts{'d'}/o);
+
+ # component left out
+ # FILE: [BUGS: 123,456]: text
+ ($file, $patbug, $nums, $text) =
+ /(NEWS|CHANGES):\s*\[*(BUG|PATCH)*(?:ES|S|):*\s*([\d,\s*]*)\]*:*\s*-*\s*(.*)/ if (!$file);
+
+ print STDERR " 5:$file, $component, $patbug, $nums, $text\n" if ($opts{'d'} && /$opts{'d'}/o);
+
+ if ($opts{'d'} && /$opts{'d'}/o) {
+ my $bogus = 1; # breakable point
+ }
+
+ if (!$file && $maybecontinue) {
+ if (/^\s*(.+)$/) {
+ $text = $1;
+ $file = $lastfile;
+ $component = $lastcomponent;
+
+ # we're going to re-add these
+ pop @{$output{$opts{'c'}}{$component}};
+ pop @{$output{$opts{'n'}}{$component}} if ($file eq 'NEWS');
+ } else {
+ $maybecontinue = 0;
+ $lasttext = "";
+ next;
+ }
+ } elsif (!$file) {
+ next;
+ }
+
+ next if (exists($stash{$text}));
+ $stash{$text} = 1;
+
+ $component = "unspecified" if (!$component);
+ if ($patbug) {
+ $lasttext .= " [$patbug $nums]: $text";
+ } else {
+ $lasttext .= " $text";
+ }
+ $lasttext =~ s/^ //; # get rid of leading spaces
+ $lasttext =~ s/^([a-z])/uc($1)/e; # capitalize the first letter
+ $text = wrap(" - "," ","$lasttext") . "\n";
+
+ #
+ # Assist with displaying categories in a sensible order
+ # snmplib first
+ # snmpd/snmp{apps}
+ # various other
+ # O/S specific (relies on upper case)
+ #
+ $component =~ s/^snmplib/00snmplib/;
+ $component =~ s/^snmp/0snmp/;
+ $component =~ s/^agent/0snmpd/; # Merge "agent" into "snmpd"
+ $component =~ s/^([A-Z])/zz\1/;
+ print STDERR " t:$file, $component, $patbug, $nums, $text\n" if ($opts{'d'} && /$opts{'d'}/o);
+ push @{$output{$opts{'c'}}{$component}}, $text;
+ push @{$output{$opts{'n'}}{$component}}, $text if ($file eq 'NEWS');
+ $lastfile = $file;
+ $lastcomponent = $component;
+ $maybecontinue = 1;
+ }
+}
+
+
+
+# save the news and changes to appropriate files
+foreach my $f ($opts{'c'}, $opts{'n'}) {
+ my $cat2;
+ open(O,">$f");
+ foreach my $cat (sort (keys(%{$output{$f}}))) {
+ ($cat2 = $cat) =~ s/^00?|^zz//;
+ print O " $cat2:\n";
+ print O sort @{$output{$f}{$cat}};
+ print O "\n";
+ }
+ close(O);
+}
+
+#######################################################################
+# getopt long gui portability code
+#
+sub LocalGetOptions {
+ if (eval {require Getopt::GUI::Long;}) {
+ import Getopt::GUI::Long;
+ Getopt::GUI::Long::Configure(qw(display_help no_ignore_case));
+ return GetOptions(@_);
+ } else {
+ require Getopt::Long;
+ Getopt::Long::Configure(qw(auto_help no_ignore_case));
+ import Getopt::Long;
+ }
+ GetOptions(LocalOptionsMap(@_));
+}
+
+sub LocalOptionsMap {
+ my ($st, $cb, @opts) = ((ref($_[0]) eq 'HASH')
+ ? (1, 1, $_[0]) : (0, 2));
+ for (my $i = $st; $i <= $#_; $i += $cb) {
+ if ($_[$i]) {
+ next if (ref($_[$i]) eq 'ARRAY' && $_[$i][0] =~ /^GUI:/);
+ push @opts, ((ref($_[$i]) eq 'ARRAY') ? $_[$i][0] : $_[$i]);
+ push @opts, $_[$i+1] if ($cb == 2);
+ }
+ }
+ return @opts;
+}