#!/usr/local/bin/perl

# "merge-newsrcs.pl"
# 
# Copyright (c) 1991 by Jonathan Kamens (jik@athena.mit.edu).
# 
# This file may be freely redistributed as long as this entire
# comment (up to the first blank line below) stays on it, and as long
# as you don't try to make any money distributing it.
# 
# Furthermore, if you make any changes to it and then redistribute
# it, please mark in some ways the changes you have made my version,
# and, if possible, forward the changes back to me.
# 
# $Id: merge-newsrcs.pl,v 1.4 91/09/01 12:59:43 jik Exp $

# This program reads .newsrc files and merges the lists of read
# articles in each newsgroup in each file.
# 
# If a newsgroup is subscribed in one file and unsubscribed in
# another, the subscription wins out.

%assoc = ();
%assocsub = ();
@ordered = ();
$hash = 0;

while ($_ = $ARGV[0], /^-/) {
    shift;
    if (/^-hash$/) {
	$hash++;
	next;
    }
    die "Unknown argument \"$_\".\n";
}

while (<>) {
    if ($hash && (($hash++ % 10) == 0)) {
	local($|) = 1;
	print STDERR "#";
    }
    next if (! /^(.*)([:!]) *(.*)$/);
    chop;
    if (! $assoc{$1}) {
	$assoc{$1} = $3;
	$assocsub{$1} = $2;
	push(@ordered, $1);
	next;
    }
    elsif ($3 ne "") {
	$assocsub{$1} = $2 if ($2 eq ":"); # subscribed wins over unsubscribed
	$assoc{$1} = &merge($assoc{$1}, $3);
    }
}

while ($group = shift @ordered) {
    if ($assoc{$group} ne "") {
	printf "$group$assocsub{$group} $assoc{$group}\n";
    }
    else {
	printf "$group$assocsub{$group}\n";
    }
}

sub merge {
    local(@ranges, $range, $merged, $last, $new, $newer);
    
    @ranges = split(/,/, @_[0]);
    push(@ranges, split(/,/, @_[1]));

    foreach $range (@ranges) {
	if ($range =~ /-/) {
	    $range = sprintf("%6d-%6d", $`, $');
	}
	else {
	    $range = sprintf("%6d-%6d", $range, $range);
	}
    }

    @ranges = sort @ranges;

    $merged = shift @ranges;

    while ($range = shift @ranges) {
	($merged =~ /......$/) && ($last = $&);
	($range =~ /-/) && (($new, $newer) = ($`, $'));
	if ($new <= $last + 1) {
	    if ($newer > $last) {
		$merged =~ s/......$//;
		$range =~ s/^.......//;
		$merged = $merged . $range;
	    }
	}
	else {
	    $merged = $merged . "," . $range;
	}
    }

    $merged =~ s/(......)-\1/$1/g;
    $merged =~ s/ //g;
    
    $merged;
}
