#!perl -w
# (C) 2003-2007 Willem Jan Hengeveld <itsme@xs4all.nl>
# Web: http://www.xs4all.nl/~itsme/
#      http://wiki.xda-developers.com/
#
# $Id$
#
use strict;
use warnings;

my %repositorymap;
my $curpath;
my $cur;
my $state=0;
$|=1;
# 0 : looking for ====
# 1 : looking for Status line
# 2 : looking for first empty
# 3 : looking for second empty, gathering attribs
sub shellescape {
    my $arg= shift;
    # ?? what do I escape for windows shell?
    return $arg;
}
my $cmdline= join(" ", map { '"'.shellescape($_).'"' } @ARGV);

open CVS, "cvs status $cmdline 2>&1 |" or die "running cvs status: $!\n";
while (<CVS>) {
    chomp;
    if ($state==0 && /^\? (.*)/) {
        my $fn=$1;

        if (-d $fn) {
            printf("NEWDIR: %s/\n", $fn);
        }
        elsif (-f $fn) {
            printf("NEWFILE: %s\n", $fn);
        }
        else {
            printf("WARNING: NEW???: %s\n", $fn);
        }
    }
    elsif ($state==0 && /^=+$/) {
        $state=1;
    }
    elsif ($state==1 && /^File: (?:no file )?(.*?)\s+Status: (.*)$/) {
        my ($filename, $status)= ($1, $2);
        $state= 2;
        if ($cur) { warn "WARNING: did not expect data in cur\n"; }
        $cur= {
            filename=> $filename,
            fullpath=> "$curpath$filename",
            status=> $status,
        };
        $state=2;

    }
    elsif ($state==2 && /^$/) {
        $state= 3;
    }
    elsif ($state==3 && /^$/) {
        $state= 0; 
        if ($cur->{status} ne "Up-to-date") {
            printf("%-20s %s\n", $cur->{status}, $cur->{fullpath} || $cur->{'Repository revision'});
        }
        $cur= undef; 
    }
    elsif ($state==3 && /^\s+(.*?):\s+(.*)/) {
        my ($name, $value)= ($1, $2);
        if (exists $cur->{$name}) {
            warn "WARNING: did not expect $name to already exist\n";
        }
        if ($name eq 'Repository revision') {
            if ($value =~ /^(.*?)(\/.*,v)/) {
                my ($rev,$repfile)= ($1, $2);
                my $i= index($repfile, $cur->{fullpath});
                if ($i==-1) {
                    warn "WARNING: path and repository file don't match:\n    repository file: $repfile\n    path: $cur->{fullpath}\n";
                }
                else {
                    $repositorymap{substr($repfile,0,$i)}++;
                }
            }
        }
        $cur->{$name}= $value;
    }
    elsif ($state==0 && /^cvs status: Examining (.*)/) {
        $curpath= "$1/";
        if ($curpath eq "./") {
            $curpath= "";
        }
    }
    else {
        warn "WARNING: unexpected line state $state: $_\n";
    }
}
close CVS;
print "---\n";
print map { sprintf("found %d files in repository %s\n", $repositorymap{$_}, $_); } keys %repositorymap;
