.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.32) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .if !\nF .nr F 0 .if \nF>0 \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} .\} .\" ======================================================================== .\" .IX Title "Parse::PlainConfig 3pm" .TH Parse::PlainConfig 3pm "2016-10-16" "perl v5.24.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Parse::PlainConfig \- Configuration file class .SH "VERSION" .IX Header "VERSION" \&\f(CW$Id:\fR lib/Parse/PlainConfig.pm, 3.03 2016/08/09 16:11:12 acorliss Exp $ .SH "SYNOPSIS" .IX Header "SYNOPSIS" .SS "\s-1SAMPLE CONFIG CLASS\s0" .IX Subsection "SAMPLE CONFIG CLASS" .Vb 1 \& package MyConfig; \& \& use Parse::PlainConfig; \& use Parse::PlainConfig::Constants; \& use base qw(Parse::PlainConfig); \& use vars qw(%_globals %_parameters %_prototypes); \& \& %_globals = ( \& \*(Aqcomment\*(Aq => \*(Aq#\*(Aq, \& \*(Aqdelimiter\*(Aq => \*(Aq:\*(Aq, \& \*(Aqlist delimiter\*(Aq => \*(Aq,\*(Aq, \& \*(Aqhash delimiter\*(Aq => \*(Aq=>\*(Aq, \& \*(Aqsubindentation\*(Aq => 4, \& \*(Aqhere doc\*(Aq => \*(AqEOF\*(Aq, \& ); \& %_parameters = ( \& \*(Aqdaemon ports\*(Aq => PPC_ARRAY, \& \*(Aqbanner\*(Aq => PPC_HDOC, \& \*(Aquser\*(Aq => PPC_SCALAR, \& \*(Aqgroup\*(Aq => PPC_SCALAR, \& \*(Aqdatabase\*(Aq => PPC_HASH, \& \*(Aqacls\*(Aq => PPC_HASH, \& ); \& %_prototypes = ( \& \*(Aqdefine net\*(Aq => PPC_ARRAY, \& ); \& \& 1; \& \& _\|_DATA_\|_ \& \& # This is the default configuration for MyConfig. \& # Newly created objects based on this class will \& # inherit the below configuration as default values. \& # \& # daemon ports: list of ports to listen on \& daemon ports: 8888, 9010 \& \& # banner: default banner to display on each connection \& banner: \& ******** WARNING ******** \& You are being watched \& ******** WARNING ******** \& EOF \& \& user: nobody \& group: nogroup \& database: \& host => localhost, \& db => mydb, \& user => dbuser, \& pass => dbpass \& \& define net loopback: 127.0.0.1/8, ::1/128 \& define net localnet: 192.168.0.0/24, 192.168.35.0/24 \& define net nonlocal: ! 192.168.0.0/16 \& \& acls: loopback => allow, localnet => allow, nonlocal => deny \& \& _\|_END_\|_ \& \& =head1 NAME \& \& normal pod text can be put here... .Ve .SS "\s-1SAMPLE OBJECT USAGE\s0" .IX Subsection "SAMPLE OBJECT USAGE" .Vb 1 \& $config = new MyConfig; \& \& print "default user: ", $config\->get(\*(Aquser\*(Aq), "\en"; \& print "default group: ", $config\->get(\*(Aqgroup\*(Aq), "\en"; \& \& # Override value \& $config\->set(\*(Aquser\*(Aq, \*(Aqroot\*(Aq); \& \& # Get config from a file \& $rv = $config\->read($filename); \& \& # Parse config from in\-memory text \& $rv = $config\->parse(@lines); \& \& # Prototyps are accessed like parameters \& @localnets = $config\->get(\*(Aqlocalnet\*(Aq); \& \& # Reset config values back to class defaults \& $config\->reset; \& \& # Print default config file \& print $config\->default; .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" \&\fBParse::PlainConfig\fR provides a simple way to write a config object class that supports all the basic primitive data types (scalar, array, and hashes) while allowing for arbitrary delimiters, comment characters, and more. .PP The use of a \fB_\|_DATA_\|_\fR block to store your default config not only provides for a reference config but a convenient way to set default values for parameters and prototypes. Use of \fB_\|_END_\|_\fR also allows you to append your standard \s-1POD\s0 text to allow for the creation of man pages documenting your configuration options. .PP The parser supports the use of \*(L"include {filename|glob}\*(R" syntax for splitting configuration parameters amongst multiple config files. Even without it every call to read or parse only applies new settings on top of the existing set, allowing you to aggregate multiple config file parameters into one set of parameters. .PP Unlike previous versions of this module \fBParse::PlainConfig\fR is strictly a parser, not a generator. That functionality never seem to be used enough to be worth maintaining with this upgrade. For backwards compatibility the old Parser/Generator is still included under the new namespace Parse::PlainConfig::Legacy. Updating legacy scripts to use that package name instead should keep everything working. .PP \&\fBParse::PlainConfig\fR is a subclass of Class::EHierarchy, and all parameters are public properties allowing access to the full set of data-aware methods provided by that module (such as \fBstore\fR, \fBpurge\fR, \fBpop\fR, \fBshift\fR, and others). .PP I/O is also done in a platform-agnostic manner, allowing parsed values to read reliably on any platform regardless of line termination style used to author the config file. .SH "SUBCLASSING" .IX Header "SUBCLASSING" All parsing objects are now subclasses of Parse::PlainConfig tuned for a specific style and a known list of parameters and/or prototypes. This makes coding for config file parsing extremely simple and convenient. .PP Control of the parser is performed by setting values in three class hashes: .ie n .SS "%_globals" .el .SS "\f(CW%_globals\fP" .IX Subsection "%_globals" The \fB\f(CB%_globals\fB\fR hash is primarily used to specify special character sequences the parser will key to identify comments and the various parameters and data types. The following key/value are supported: .PP .Vb 10 \& Key Default Description \& \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \& comment # Character(s) used to denote comments \& delimiter : Parameter/value delimiter \& list delimiter , Ordinal array values delimiter \& hash delimiter => Hash values\*(Aq key/value pair delimiter \& subindentation 4 Default level of indentation to \& expect for line continuations \& here doc EOF Token used for terminating here doc \& parameter values .Ve .PP If all of the defaults are acceptable this hash can be omitted entirely. .PP Note that the \fIsubindentation\fR is merely advisory, any additional level of subindentation on line continuations will work. What this does, however, is trim up to that amount of preceding white space on each line within a here-doc. This allows one to indent blocks of text to maintain the visual flow of the config file, while still allowing the editor the use of all columns in the display. .ie n .SS "%_parameters" .el .SS "\f(CW%_parameters\fP" .IX Subsection "%_parameters" The \fB\f(CB%_parameters\fB\fR hash is used to list all of the formal parameters recognized by this config object. All parameters must be one of four data types: .PP .Vb 6 \& Type Description \& \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \& PPC_SCALAR Simple strings \& PPC_ARRAY Arrays/lists \& PPC_HASH Hashes/Associative arrays \& PPC_HDOC Essentially a PPC_SCALAR that preserves formatting .Ve .PP All but \fB\s-1PPC_HDOC\s0\fR will trim leading/trailing white space and collapse all lines into a single line for parsing. That means that no string, ordinal value, key, or associative value can have embedded line breaks. You can, however, have delimiter characters as part of any values as long as they are encapusated in quoted text or escaped. .PP \&\fB\s-1PPC_HDOC\s0\fR will preserve line breaks, but will trim leading white space on each line up to the value given to \fB\f(CB$_globals\fB{subindentation}\fR. .ie n .SS "%_prototypes" .el .SS "\f(CW%_prototypes\fP" .IX Subsection "%_prototypes" \&\fB\f(CB%_prototypes\fB\fR exist to allow for user-defined parameters that fall outside of the formal parameterss in \fB\f(CB%_parameters\fB\fR. ACLs, for instance, are often of indeterminate number and naming, which is a perfect use-case for prototypes. .PP Like parameters prototypes are assigned a data type. Unlike parameters prototypes are assigned types based on a declarative preamble since the the name (or token) is not known in advance. .PP To continue with the \s-1ACL\s0 example we could define a prototype like so: .PP .Vb 1 \& %_prototypes = ( \*(Aqdefine acl\*(Aq => PPC_ARRAY ); .Ve .PP The config editor could then define any number of ACLs: .PP .Vb 2 \& define acl loopback 127.0.0.1/8 \& define acl localnet 192.168.0.0/24,192.168.1.0/24 .Ve .PP Once parsed those \s-1ACL\s0 parameters can then be accessed simply by their unique token: .PP .Vb 1 \& @localnets = $config\->get(\*(Aqlocalnet\*(Aq); .Ve .SH "CONFIG FILE FORMAT RULES" .IX Header "CONFIG FILE FORMAT RULES" This module is intended to provide support for parsing human-readable config files, while supporting basic data structures and delimiter flexibility. That said, there are a few basic rules by which the parser operates. .PP Note that the use \fB_\|_DATA_\|_\fR and/or \fB_\|_END_\|_\fR blocks are entirely optional. .SS "\s-1DELIMITERS\s0" .IX Subsection "DELIMITERS" Delimiters must be unique. You cannot use the same character(s) for both list delimiters and hash key/value pair delimiters, for instance. That said, the parser is very forgiving on the use of whitespace around all delimiters, even if one of your delimiters is literally a space. .PP Hash and array delimiters can be embedded in elements as long as they're quoted or escaped appropriately. Those elements are split using Text::ParseWords' quotewords function. .SS "\s-1LINE CONTINUATIONS\s0" .IX Subsection "LINE CONTINUATIONS" Parameters values may need to be, by necessity, longer than a single line. This is fully supported for all data types. All that is needed that the line continuations be at least one space more indented than the preceding line. Empty lines are considered to be line breaks which terminate the parameter value. Likewise, a line that is indented equal or less than the parameter declaration line implies a new block of content. .PP There is one exception to that rule: here docs. If you need to preserve formatting, which can include line breaks, the use of here docs will suck in everything up to the next here doc \s-1EOF\s0 token. The entire here doc, however, is treated as scalar value for purposes of parameter storage. .SS "\s-1COMMENTS\s0" .IX Subsection "COMMENTS" Comments can be any sequence of characters, but must be on a line by themselves. Preceding white space is allowed. .SS "\s-1PARAMETER NAMES\s0" .IX Subsection "PARAMETER NAMES" Given that parameters are actually formal object properties it could go without saying that each parameter must be uniquely named. Parameters names can include white space or other miscellaneous punctuation. .SS "\s-1PROTOTYPES\s0" .IX Subsection "PROTOTYPES" Prototypes allow for the dynamic creation of parameters. There are a few caveats in their usage, however. Prototypes are specified through a unique preamble followed by a unique token. Unlike parameter names this token cannot have embedded white space. But like parameters they are specified by that unique token (minus the preamble) during get and set operations. .PP Since these dynamic properties are also formal properties the token must not be in use as a formal property. In other words, all prototype tokens and parameter names must be unique as a set. .PP Parsing errors will be generated if the token occurs as a formal parameter. It will also be generated if you attempt to redfine a token as a different type of data structure. .SH "SUBROUTINES/METHODS" .IX Header "SUBROUTINES/METHODS" .SS "new" .IX Subsection "new" .Vb 1 \& $conf = new MyConfig; .Ve .PP This creates a new config object based on the specified config class, initialized with the defaults stored in \fB_\|_DATA_\|_\fR. No additional arguments are supported. This will fail if the default config is invalid in any way. .SS "settings" .IX Subsection "settings" .Vb 1 \& $settings = $config\->settings; .Ve .PP This provides a reference to the engine settings object from which you can interrogate various settings such as delimiters, etc. The full set of methods supported by the settings object is documented in Parse::PlainConfig::Settings. .SS "default" .IX Subsection "default" .Vb 2 \& $text = $config\->default; \& @lines = $config\->default; .Ve .PP This returns the text of the default configuration file embedded in the \&\fB_\|_DATA_\|_\fR section of the config class. .SS "get" .IX Subsection "get" .Vb 3 \& $val = $config\->get($parameter); \& @val = $config\->get($parameter); \& %val = $config\->get($parameter); .Ve .PP This returns the stored value(s) for the specified parameter. It is essentially the same as using the parent class property method, although this will not cause the program to croak like property does. It will carp, instead. .SS "set" .IX Subsection "set" .Vb 4 \& $rv = $config\->set($parameter); \& $rv = $config\->set($parameter, $newval); \& $rv = $config\->set($parameter, @newval); \& $rv = $config\->set($parameter, %newval); .Ve .PP This method sets the desired parameter to the newly specified value(s). If no values are provided it will assume that you wish to set scalars to \fBundef\fR or empty arrays and hashes. .SS "parse" .IX Subsection "parse" .Vb 2 \& $rv = $config\->parse($text); \& $rv = $config\->parse(@lines); .Ve .PP This will parse and set any parameters or prototypes found in the content. It will return false if any parsing errors are found (spurious text, etc.) but will extract everything of intelligible value it can. .SS "read" .IX Subsection "read" .Vb 4 \& $rv = $config\->read($filename); \& $rv = $config\->read(@files); \& $rv = $config\->read($pglob); \& $rv = $config\->read(*fh); .Ve .PP This method will attempt to read every file passed to it, whether it be passed by file name, file handle, Paranoid::Glob, or objec reference support I/O functions. Fair warning: this does observe file locking semantics (flock) and it will close any file handles passed to it after consuming the content. .PP Also note that this method uses Paranoid::IO::Line, which implements protections against memory-utilization attacks. You may need to adjust the following parameters depending on the size of your config files: .PP .Vb 2 \& use Paranoid::IO qw(PIOMAXFSIZE PIOBLKSIZE); \& use Paranoid::IO qw(PIOMAXLNSIZE); \& \& # Adjust read block size for performance \& PIOBLKSIZE = 16 * 1024; \& \& # Allow file sizes up to 128KB \& PIOMAXFSIZE = 128 * 1024; \& \& # Allow individual lines to be 4KB long \& PIOMAXLNSIZE = 4 * 1024; .Ve .SS "reset" .IX Subsection "reset" .Vb 1 \& $rv = $config\->reset; .Ve .PP This method purges the contents of all parameters and prototypes, then applies the default settings as found in \fB_\|_DATA_\|_\fR. .SS "prototyped" .IX Subsection "prototyped" .Vb 2 \& @protos = $config\->prototyped; \& @protos = $config\->prototyped($preamble); .Ve .PP This method returns a list of properties that were defined as the result of prototypes. With no arguments it returns all properties that were defined. With an argument it returns only those properties that were defined by that specific prototype preamble. .SS "error" .IX Subsection "error" .Vb 1 \& $errStr = $config\->error; .Ve .PP Returns the last error that occurred. Note that this isn't reset between method invocations. .SH "DEPENDENCIES" .IX Header "DEPENDENCIES" .IP "o" 4 .IX Item "o" Class::EHierarchy .IP "o" 4 .IX Item "o" Fcntl .IP "o" 4 .IX Item "o" Paranoid .IP "o" 4 .IX Item "o" Paranoid::Debug .IP "o" 4 .IX Item "o" Paranoid::Glob .IP "o" 4 .IX Item "o" Paranoid::IO .IP "o" 4 .IX Item "o" Paranoid::IO::Line .IP "o" 4 .IX Item "o" Paranoid::Input .IP "o" 4 .IX Item "o" Parse::PlainConfig::Constants .IP "o" 4 .IX Item "o" Parse::PlainConfig::Settings .IP "o" 4 .IX Item "o" Text::ParseWords .IP "o" 4 .IX Item "o" Text::Tabs .SH "DIAGNOSTICS" .IX Header "DIAGNOSTICS" Through the use of \fBParanoid::Debug\fR this module will produce internal diagnostic output to \s-1STDERR. \s0 It begins logging at log level 7. To enable debugging output please see the pod for Paranoid::Debug. .SH "BUGS AND LIMITATIONS" .IX Header "BUGS AND LIMITATIONS" .SH "AUTHOR" .IX Header "AUTHOR" Arthur Corliss (corliss@digitalmages.com) .SH "LICENSE AND COPYRIGHT" .IX Header "LICENSE AND COPYRIGHT" This software is licensed under the same terms as Perl, itself. Please see http://dev.perl.org/licenses/ for more information. .PP (c) 2002 \- 2016, Arthur Corliss (corliss@digitalmages.com)