summaryrefslogtreecommitdiffabout
path: root/lib/Config/Parser/Ini.pm
Side-by-side diff
Diffstat (limited to 'lib/Config/Parser/Ini.pm') (more/less context) (ignore whitespace changes)
-rw-r--r--lib/Config/Parser/Ini.pm96
1 files changed, 96 insertions, 0 deletions
diff --git a/lib/Config/Parser/Ini.pm b/lib/Config/Parser/Ini.pm
new file mode 100644
index 0000000..b3a1ef9
--- a/dev/null
+++ b/lib/Config/Parser/Ini.pm
@@ -0,0 +1,96 @@
+package Config::Parser::Ini;
+use strict;
+use warnings;
+use parent 'Config::Parser';
+use Carp;
+use Text::ParseWords;
+
+sub parse {
+ my $self = shift;
+ $self->{_filename} = shift // confess "No filename given";
+ local %_ = @_;
+ $self->debug(1, "parsing $self->{_filename}");
+ $self->_readconfig($self->{_filename}, %_);
+ return $self;
+}
+
+sub filename { shift->{_filename} }
+
+# _readconfig(FILE)
+sub _readconfig {
+ my $self = shift;
+ my $file = shift;
+ local %_ = @_;
+ my $fh = delete $_{fh};
+ my $need_close;
+
+ $self->debug(1, "reading file $file");
+ unless ($fh) {
+ open($fh, "<", $file)
+ or do {
+ $self->error("can't open configuration file $file: $!");
+ $self->{_error_count}++;
+ return 0;
+ };
+ $need_close = 1;
+ }
+
+ my $line = delete $_{line} // 0;
+ my @path;
+ my $include;
+
+ while (<$fh>) {
+ ++$line;
+ chomp;
+ if (/\\$/) {
+ chop;
+ $_ .= <$fh>;
+ redo;
+ }
+
+ s/^\s+//;
+ s/\s+$//;
+ s/#.*//;
+ next if ($_ eq "");
+
+ my $locus = new Config::Tree::Locus($file, $line);
+
+ if (/^\[(.+?)\]$/) {
+ @path = parse_line('\s+', 0, $1);
+ if (@path == 1 && $path[0] eq 'include') {
+ $include = 1;
+ } else {
+ $include = 0;
+ $self->add_node(\@path,
+ new Config::Tree::Node::Section(locus => $locus));
+ }
+ } elsif (/([\w_-]+)\s*=\s*(.*)/) {
+ my ($k, $v) = ($1, $2);
+ $k = lc($k) if $self->{_ci}; #FIXME:private member
+
+ if ($include) {
+ if ($k eq 'path') {
+ $self->_readconfig($v);
+ } elsif ($k eq 'pathopt') {
+ $self->_readconfig($v) if -f $v;
+ } elsif ($k eq 'glob') {
+ foreach my $file (bsd_glob($v, 0)) {
+ $self->_readconfig($file);
+ }
+ } else {
+ $self->error("keyword \"$k\" is unknown", locus => $locus);
+ $self->{_error_count}++;
+ }
+ } else {
+ $self->add_value([@path, $k], $v, $locus);
+ }
+ } else {
+ $self->error("malformed line", locus => $locus);
+ $self->{_error_count}++;
+ }
+ }
+ close $fh if $need_close;
+}
+
+1;
+

Return to:

Send suggestions and report system problems to the System administrator.