The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
use strict;
use warnings;

use Carp;

# Checks that the following relationships hold set-wise (e.g. ignoring order):
#
#  keys($self->{v}) = $self->{sects}
#
# And for every section $sect:
#
#  keys($self->{v}{sect}) = $self->{v}{params}
#
# This should be the case whenever control flows outside this module. Croaks
# upon any error.
sub Config::IniFiles::_assert_invariants {
	my ($self)=@_;
	my %set;
	foreach my $sect (@{$self->{sects}}) {
		croak "Non-lowercase section $sect" if ($self->{nocase} &&
											  (lc($sect) ne $sect));
		$set{$sect}++;
	}
	foreach my $sect (keys %{$self->{v}}) {
		croak "Key $sect in \$self->{v} and not in \$self->{sects}" unless
		  ($set{$sect}++);
	}
	grep { croak "Key $_ in \$self->{sects} and not in in \$self->{v}" unless
	   $set{$_} eq 2 } (keys %set);

	foreach my $sect (@{$self->{sects}}) {
		%set=();

		foreach my $parm (@{$self->{parms}{$sect}}) {
			croak "Non-lowercase parameter $parm" if ($self->{nocase} &&
													(lc($parm) ne $parm));
			$set{$parm}++;
		}
		foreach my $parm (keys %{$self->{v}{$sect}}) {
			croak "Key $parm in \$self->{v}{'$sect'} and not in \$self->{parms}{'$sect'}"
			  unless ($set{$parm}++);
		}
		grep { croak "Key $_ in \$self->{parms}{'$sect'} and not in in \$self->{v}{'$sect'}"
				 unless $set{$_} eq 2 } (keys %set);
	}
}

1;