6 our %candidates; # $candidates{CAND}{Desc}, {Opts}[]
9 my $candvoter_re = '\w+';
12 die "bad input: $_[0]";
15 sub normalise_opts_list ($) {
19 foreach my $o (split /\s+/, $os) {
22 } elsif ($o =~ m/^\w+\=\S+$/) {
24 } elsif ($o !~ m/\S/) {
26 badinput "bad option \`$o'";
32 sub normalise_opts ($) {
34 my @o = normalise_opts_list $os;
44 push @options, normalise_opts_list $';
45 } elsif (m/^($candvoter_re?)\s*=\s*([^|]+?)\s*\|(.*)?$/o) {
47 print STDERR Dumper($1,$2,$3);
48 my ($cand,$desc,$opts) = ($1,$2,$3);
49 push @{ $candidates{$cand}{Opts} }, normalise_opts $opts;
51 badinput "multiple descriptions for $cand" if
52 defined $candidates{$cand}{Desc};
53 $candidates{$cand}{Desc} = $desc;
55 } elsif (m/^($candvoter_re?)?\s*\:([^|]*)(?:\|(.*))?$/) {
56 my ($voter,$opts) = ($1,$3);
58 foreach my $p (split /\s+/, $2) {
59 if ($p =~ m/^\w+(?:\=\w+)*$/) {
61 $candidates{$_} //= { } foreach $p =~ m/\w+/g;
63 # empty entry can only happen if voter casts no prefs at all
65 badinput "bad vote preference \`$p'";
68 push @ballots, "$voter : @p".normalise_opts $opts;
71 badinput "unknown line format \`$_'";
75 print "| @options\n" or die $!;
77 foreach my $cand (sort keys %candidates) {
78 my $c = $candidates{$cand};
81 my $opts = $c->{Opts};
82 print "$cand = $c->{Desc} | @$opts\n" or die $!;
85 sub vsortkey { $_[0] =~ m/:/; return "$' : $`"; }
87 print $_,"\n" or die $! foreach
88 sort { vsortkey($a) cmp vsortkey($b) } @ballots;
90 print ".\n" or die $!;