I'm in the process of trying to clean up a script I wrote some time ago, one that has a number of different variable values.

As an exercise to sharpen some of my basic skills, I decided to write a simple configuration file parser. The idea, of course, being to move the variable data into a separate files that could be edited as needed.

Now, I am fully aware that CPAN provides the AppConfig module, among others. Normally, I'm a strong advocate for using CPAN whenever possible. In this case, however, there are a number of factors that lead to me this exercise:

  1. I wanted to do it.
  2. I am not the admin on the server that will eventually host the final script.
  3. The admin in question is reluctant to install additional modules (for lots of bad reasons that have been previously discussed).
  4. I am reluctant to cause a political scene (I have a bad enough reputation as it is).

Are these good reasons for not installing AppConfig? Of course not. Again, my primary purpose for doing this was to sharpen my skills. (Put another way, I'm fully aware that I'm reinventing a wheel, but I think I have good reasons for doing so.)

In any event, here's my current version and I would appreciate any feedback or suggestions.

#!/usr/bin/perl -w use strict; use File::Basename; my $cfgfile = "/datapath/filename.cfg"; my %settings = readConfigData( $cfgfile ); my $novalues = scalar( keys( %settings ) ); # Since we're done with the file name; reuse the var ( $cfgfile ) = fileparse( $cfgfile ); print "The $cfgfile file contains ", "the following settings and values:\n\n", map { " $_ = $settings{ $_}\n" } sort keys %settings; print "\n", "$novalues settings were found in all."; sub readConfigData # -------------------------------------------------------------- # Returns a hash containing setting names and values from the # configuration file. Note that the name of the configuration # file is passed as the first parameter. # -------------------------------------------------------------- { my $filename = shift; # name of the config file. my $filedata = ""; # holds a line read from the file my %settings = (); # holds results returned to caller my $cfglabel = ""; # holds name of a setting my $cfgvalue = ""; # holds value of a setting open( DATAFILE, "< $filename" ) or die "Can't Open $filename; reason: $!\n"; while ( <DATAFILE> ) { chomp; $filedata = trim( $_ ); # save line into var. # ignore comments and blank lines if ( ( substr( $filedata, 0, 1 ) eq '#' ) or ( $filedata eq "" ) ) { next; } else # it looks like data, so split it up, trim # white space and save it into the hash. { ( $cfglabel, $cfgvalue ) = split( /=/ ); $cfglabel = trim( $cfglabel ); $cfgvalue = trim( $cfgvalue ); $settings{ $cfglabel } = $cfgvalue; } } close( DATAFILE ) or die "Can't Close $filename; reason: $!\n"; return %settings; } sub trim # -------------------------------------------------------------- # Removes white space from either side of a value. Used in a few # places. # -------------------------------------------------------------- { my $value = shift; $value =~ s/^\s+//; # trim leading white space $value =~ s/\s+$//; # trim trailing white space return $value }

In this example script, I'm simply dumping the contents of the configuration file itself. Note that all values have been mangled to protect the guilty.

The data file itself is, as you can probably tell, loosely based on the Windows .INI format, though I don't include support for sections or for arrays. The depth of the support is fine for my current configuration needs.

An example .cfg file might be something along these lines:

HTMLHEAD = \data\htmlhead.html HTMLFOOT = \data\htmlfoot.html MAILHOST = mail.example.com MAILTO = <username\@example.com> MAILFROM = <sender\@example.com> MAILCOPY = <someoneelse\@example.com> LOCKTRYS = 10 DATAFILE = \data\counter.dat

You get the idea.

Thanks in advance...

--f


In reply to Simple Configuration Parser by footpad

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.