# -*- cperl -*- package My::Config::Option; use strict; use warnings; sub new { my ($class, $option_name, $option_value)= @_; my $self= bless { name => $option_name, value => $option_value }, $class; return $self; } sub name { my ($self)= @_; return $self->{name}; } sub value { my ($self)= @_; return $self->{value}; } package My::Config::Group; use strict; use warnings; sub new { my ($class, $group_name)= @_; my $self= bless { name => $group_name, options => [], options_by_name => {}, }, $class; return $self; } sub insert { my ($self, $option_name, $value, $if_not_exist)= @_; my $option= $self->option($option_name); if (defined($option) and !$if_not_exist) { $option->{value}= $value; } else { my $option= My::Config::Option->new($option_name, $value); # Insert option in list push(@{$self->{options}}, $option); # Insert option in hash $self->{options_by_name}->{$option_name}= $option; } return $option; } sub remove { my ($self, $option_name)= @_; # Check that option exists my $option= $self->option($option_name); return undef unless defined $option; # Remove from the hash delete($self->{options_by_name}->{$option_name}) or die; # Remove from the array @{$self->{options}}= grep { $_->name ne $option_name } @{$self->{options}}; return $option; } sub options { my ($self)= @_; return @{$self->{options}}; } sub name { my ($self)= @_; return $self->{name}; } # # Return a specific option in the group # sub option { my ($self, $option_name)= @_; return $self->{options_by_name}->{$option_name}; } # # Return a specific value for an option in the group # sub value { my ($self, $option_name)= @_; my $option= $self->option($option_name); die "No option named '$option_name' in this group" if ! defined($option); return $option->value(); } package My::Config; use strict; use warnings; use IO::File; use File::Basename; # # Constructor for My::Config # - represents a my.cnf config file # # Array of arrays # sub new { my ($class, $path)= @_; my $group_name= undef; my $self= bless { groups => [] }, $class; my $F= IO::File->new($path, "<") or die "Could not open '$path': $!"; while ( my $line= <$F> ) { chomp($line); # [group] if ( $line =~ /\[(.*)\]/ ) { # New group found $group_name= $1; #print "group: $group_name\n"; $self->insert($group_name, undef, undef); } # Magic #! comments elsif ( $line =~ /^#\!/) { my $magic= $line; die "Found magic comment '$magic' outside of group" unless $group_name; #print "$magic\n"; $self->insert($group_name, $magic, undef); } # Comments elsif ( $line =~ /^#/ || $line =~ /^;/) { # Skip comment next; } # Empty lines elsif ( $line =~ /^$/ ) { # Skip empty lines next; } # !include elsif ( $line =~ /^\!include\s*(.*?)\s*$/ ) { my $include_file_name= dirname($path)."/".$1; # Check that the file exists die "The include file '$include_file_name' does not exist" unless -f $include_file_name; $self->append(My::Config->new($include_file_name)); } #