NAME
    Config::INI::RefVars - INI file reader with variable references and
    function calls

VERSION
    Version #VERSION#

SYNOPSIS
      use Config::INI::RefVars;

      my $cfg = Config::INI::RefVars->new();
      $cfg->parse_ini(src => 'config.ini');
      my $vars = $cfg->variables;
      print $vars->{database}{host}, "\n";

QUICK EXAMPLE
    Suppose config.ini contains

      root = /usr/local

      [paths]
      bin = $(root)/bin
      lib = $(root)/lib
      cfg = $(=& catfile, $(lib), config.ini)

      [copy]
      cfg = $([paths]cfg)

    Then

      my $cfg = Config::INI::RefVars->new();

      $cfg->parse_ini(src => 'config.ini');

      my $vars = $cfg->variables;

    produces

      {
        '__TOCOPY__' => {
          root => '/usr/local',
        },
        paths => {
          root => '/usr/local',
          bin  => '/usr/local/bin',
          lib  => '/usr/local/lib',
          cfg  => '/usr/local/lib/config.ini',
        },
        copy => {
          root => '/usr/local',
          cfg  => '/usr/local/lib/config.ini',
        },
      }

DESCRIPTION
  INTRODUCTION
    "Config::INI::RefVars" extends the traditional INI format with variable
    references, function calls, include directives, line continuations, and
    additional assignment operators. All references are resolved while
    parsing, so the resulting data structure contains only plain Perl
    scalars.

    The minimum Perl version required to use this module is "v5.10.1".

  OVERVIEW
    A line in an INI file should normally not start with an "=" or the
    sequence ";!". These are reserved for extensions (e.g. "=include").
    Otherwise the parser throws a "Directives are not yet supported"
    exception. Apart from these special cases, the following rules apply:

    *   Spaces at the beginning and end of each line are ignored.

    *   If the first non-white character of a line is a ";" or a "#", then
        the line is a comment line.

    *   Comments can also be specified to the right of a section declaration
        (in this case, the comment must not contain closing square
        brackets).

    *   In a section header, spaces to the right of the opening square
        bracket and to the left of the closing square bracket are ignored,
        i.e. a section name always begins and ends with a non-white
        character. But: As a special case, the name of a section heading can
        be an empty character string.

    *   Section name must be unique.

    *   The order of the sections is retained: The "sections" method returns
        an array of sections in the order in which they appear in the INI
        file.

    *   There are several assignment operators, not just "=". The other
        assignment operators have one or more punctuation characters to the
        left of the "=" symbol.

    *   Spaces around the assignment operator are usually ignored, but may
        be needed as separators in some cases.

    *   If you want to define a variable whose name ends with an punctuation
        character other than an underscore, there must be at least one space
        between the variable name and the assignment operator.

    *   The name of a user-defined variable cannot be empty. Furthermore, it
        cannot begin with any of the characters ";", or "[". Obviously, it
        also cannot contain a "=" at all (but see constructor variable
        "tocopy_vars").

    *   The sequence "$(...)" is used to reference INI variables or
        environment variables.

    *   The sequence "$(=& ...)" is used to call built-in functions.

    *   The sequence "$(=# ...)" is used to call user-defined functions.

    *   There is no escape character.

    *   The source to be parsed (argument "src" of the method "parse_ini")
        does not have to be a file, but can also be a string or an array.

    You will find further details in the following sections.

  SECTIONS
    A section begins with a section header:

      [section]

    A line contains a section heading if the first non-blank character is a
    "[" and the last non-blank character is a "]". The character string in
    between is the name of the section, whereby spaces to the right of "["
    and to the left of "]" are ignored.

       [   The name of the section   ]

    This sets the section name to "The name of the section".

    As a special case, "[]" or "[ ]" are permitted, which results in a
    section name that is just an empty string.

    Section names must be unique.

    An INI file does not have to start with a section header, it can also
    start with variable definitions. In this case, the variables are added
    to the *tocopy* section (default name: "__TOCOPY__"). You can explicitly
    specify the *tocopy* section heading, but then this must be the first
    active line in your INI file.

  ASSIGNMENT OPERATORS
   Overview
    There are several assignment operators, the basic one is the "=", the
    others are formed by a "=" preceded by one or more punctuation
    characters. Thus, if you want to define a variable whose name ends with
    an punctuation character, there must be at least one space between the
    variable name and the assignment operator.

    Note: Since the use of the underscore in identifiers is so common, it is
    not treated as a punctuation character here.

   List of Assignment Operators
    "=" The standard assignment operator. Note: A second assignment to the
        same variable simply overwrites the first.

    "?="
        Works like the corresponding operator of GNU Make: the assignment is
        only executed if the variable is not yet defined.

    "??="
        This works similarly to the "?=" operator: the assignment is only
        executed if the variable is not yet defined or if its current,
        non-expanded value is an empty string.

        This allows you to set a default value for an environment variable:

           env_var:=$(=ENV:ENV_VAR)
           env_var??=the default

        If the environment variable "ENV_VAR" is not defined or is empty,
        then "env_var" has the value "the default". This would not work with
        "?=". Please note that you must also use the ":=" operator for the
        assignment!

    ":="
        Works like the corresponding operator of GNU Make: all references to
        other variables are expanded when the variable is defined. See
        section "REFERENCING VARIABLES"

    ".="
        The right-hand side is appended to the value of the variable. If the
        variable is not yet defined, this does the same as a simple "=".

        Example:

          var=abc
          var.=123

        Now "var" has the value "abc123".

    "+="
        The right-hand side is appended to the value of the variable,
        separated by a space. If the right-hand side is empty, a space is
        appended. If the variable is not yet defined, this has the same
        effect as a simple "=".

        Example:

           var=abc
           var+=123

        Now "var" has the value "abc 123".

        Note: The semantics of the "+=" operator are intentionally based on
        GNU Make up to version 4.2.1. Consequently, an assignment such as

          foo =
          foo +=

        appends a single space rather than an empty string. GNU Make changed
        this behavior in version 4.3.

    ".>="
        The right-hand side is placed in front of the value of the variable.
        If the variable is not yet defined, this has the same effect as a
        simple "=".

        Example:

          var=abc
          var.>=123

        Now "var" has the value "123abc".

    "+>="
        The right-hand side is placed in front the value of the variable,
        separated by a space. If the right-hand side is empty, a space is
        placed in front of the variable value. If the variable is not yet
        defined, this has the same effect as a simple "=".

        Example:

          var=abc
          var+>=123

        Now "var" has the value "123 abc".

    "#="
        Defines a function. See "User-defined Functions"

    "\=", ":\=", etc
        See "LINE CONTINUATION".

  LINE CONTINUATION
    By default, the value assigned in an assignment statement ends at the
    first non-space character on the same line. However, this module also
    supports line continuations by modifying the assignment operators.

    To enable line continuation, place a backslash immediately before the
    assignment operator. This works with all assignment operators, for
    example "\=", ":\=", "+\=", etc. The backslash must appear immediately
    before the equals sign.

    If a line containing such a modified assignment operator ends with a
    backslash, the trailing backslash is removed and the following physical
    line is appended. This process is repeated until a line no longer ends
    with a backslash or the end of the file is reached.

    Spaces following a backslash are always ignored, because spaces at the
    end of a line are removed before parsing.

    Note: The backslash preceding the assignment operator is only a marker
    to enable line continuation and is not part of the operator itself.

    Examples:

      long_line \= foo\
        bar\
        baz

    is equivalent to

      long_line = foo  bar  baz

    Likewise,

      text :\= Hello,\
      world!

    is equivalent to

      text := Hello,world!

    Assignments without a backslash before the assignment operator never use
    line continuation, even if their value ends with a backslash.

      normal = foo\
      bar = baz

    Here, the variable "normal" has the value "foo\", and the variable "bar"
    has the value "baz".

    Note: To avoid ambiguity, the first character of a continuous line must
    not be "=". This

      v\=abcd\
      =

    will cause a "directive in line continuation" error, but this will work:

      v\=abcd\
       =

    This works because of the space before the "=", the result would be
    "abcd =".

    This would work, too:

      v\=abcd\
      $()=

    The result would be "abcd=".

  INCLUDE FILES
    An INI file may include another INI file by using the "=include"
    directive:

      =include common.ini

    The file name may contain variable references:

      config_dir = config

      =include $(config_dir)/common.ini

    If the specified file name is relative, it is interpreted relative to
    the directory containing the current INI file. Absolute file names may
    also be used.

    An included file is processed exactly as if its contents had been
    inserted at the position of the "=include" directive. Consequently, the
    current section is preserved across file boundaries. If the included
    file changes the current section, parsing continues in that section
    after the include.

    The same file may be included multiple times. However, recursive
    includes are detected and reported as an error.

    Examples:

      [general]

      =include common.ini

      name = example

    If common.ini contains

      version = 1.0

    the resulting input is equivalent to

      [general]

      version = 1.0

      name = example

    Likewise,

      [first]

      =include other.ini

      value = x

    where other.ini contains

      [second]

      other = y

    is equivalent to

      [first]

      [second]

      other = y

      value = x

    Line continuation never crosses file boundaries. In particular, a
    directive must not appear where a continuation line is expected.

  REFERENCING VARIABLES
   Basic Referencing
    The referencing of variables is similar but not identical to that in
    make, you use "$(*VARIABLE*)". Example:

       a=hello
       b=world
       c=$(a) $(b)

    Variable "c" has the value "hello world". As with make, lazy evaluation
    is used, i.e. you would achieve exactly the same result with this:

       c=$(a) $(b)
       a=hello
       b=world

    But the following would result in "c" containing only one space:

       c:=$(a) $(b)
       a=hello
       b=world

    Unlike in make, the round brackets cannot be omitted for variables with
    only one letter!

    You can nest variable references:

       foo=the foo value
       var 1=fo
       var 2=o
       bar=$($(var 1)$(var 2))

    Now the variable "bar" has the value "the foo value".

    A reference to a non-existent variable is always expanded to an empty
    character string.

    If you need a literal "$(...)" sequence, e.g. "$(FOO)", as part of a
    variable value, you can write:

       var = $$()(FOO)

    This results in the variable "var" having the value "$(FOO)". It works
    because "$()" always expands to an empty string (see section "PREDEFINED
    VARIABLES").

    Recursive references are not possible, an attempt to do so leads to a
    fatal error. However, you can do the following with the ":=" assignment:

       a=omethin
       a:=s$(a)g

    "a" has the value "something". However, due to the way ":=" works, this
    is not really a recursive reference.

   Referencing Variables of other Sections
    By default, you can reference a variable in another section by writing
    the name of the section in square brackets, followed by the name of the
    variable:

       [sec A]
       foo=Referencing a variable from section: $([sec B]bar)

       [sec B]
       bar=Referenced!

    You can switch to a different notation by specifying the constructor
    argument "separator".

    A more complex example:

       [A]
       a var = 1234567

       [B]
       b var = a var
       nested = $([$([C]c var)]$(b var))

       [C]
       c var = A

    Variable "nested" in section "B" has the value 1234567:

    *   "$([C]c var)" expands to "A",

    *   "$(b var)" expands to "a var",

    *   We therefore have "$([A]a var)" which leads to 1234567.

  PREDEFINED VARIABLES
   Variables related to Section and Variable Names
    "=" "$(=)" expands to the name of the current section.

    "=="
        "$(==)" expands to the name of the variable that is currently being
        defined. Think of this as a pseudo-variable, something like
        $([SECTION]==) always results in an empty string.

    Example:

       [A]
       foo=variable $(==) of section $(=)
       ref=Reference to foo of section B: $([B]foo)

       [B]
       foo=variable $(==) of section $(=)
       bar=$(foo)

    The hash returned by the "variables" method is then:

       {
         'A' => {
                 'foo' => 'variable foo of section A',
                 'ref' => 'Reference to foo of section B: variable foo of section B'
                },
         'B' => {
                 'foo' => 'variable foo of section B'
                 'bar' => 'variable foo of section B',
                }
       }

   Variables related to the Source
    "=srcname"
        Name of the INI source. If the source is a file, this corresponds to
        the value that you have passed to "parse_ini" via the "src"
        argument, otherwise it is set to "INI data". The value can be
        overwritten with the argument "src_name".

    "=INIdir", "=INIfile"
        Directory (absolute path) and file name of the INI file. These
        variables are only present if the source is a file, otherwise they
        are not defined.

   Variables related to the OS
    "=:"
        The directory separator, "\" on Windows, "/" on Linux. Note: This is
        not always sufficient to create a path, e.g. on VMS.

    "=::"
        Path separator, which is used in the environment variable "PATH",
        for example.

   Space Variables
    "$()" always expands to an empty string, "$( )", "$(  )" with any number
    of spaces within the parens expand to exactly these spaces. So there are
    several ways to define variables with heading or trailing spaces:

       foo = abc   $()
       bar = $(   )abc

    The value of "foo" has three spaces at the end, the value of "bar" has
    three spaces at the beginning. A special use case for "$()" is the
    avoidance of unwanted variable expansion:

       var=hello!
       x=$(var)
       y=$$()(var)

    With these settings, "x" has the value "Hello!", but "y" has the value
    "$(var)".

   Other Variables
    "=TO_CP_SEC"
        Name of the *tocopy* section, see "THE *TOCOPY* SECTION".

    "=VERSION"
        Version of the "Config::INI::RefVars" module.

    "=devnull"
        A string representation of the null device (result of function
        "devnull" from File::Spec::Functions).

    "=rootdir"
        A string representation of the root directory (result of function
        "rootdir" from File::Spec::Functions).

    "=tmpdir"
        A string representation of the first writable directory from a list
        of possible temporary directories, or the current directory if no
        writable temporary directories are found (result of function
        "tmpdir" from File::Spec::Functions).

   Custom predefined Variables
    Currently, custom predefined variables are not supported. But you can do
    something very similar, see argument "tocopy_vars" (of "new" and
    "parse_ini"), see also "THE *TOCOPY* SECTION". With this argument you
    can also define variables whose names contain a "=", which is obviously
    impossible in an INI file.

   Predefined Variables in resulting Hash
    By default, all variables whose names contain a "=" are removed from the
    resulting hash. This means that the variables discussed above are not
    normally included in the result. This behavior can be changed with the
    "parse_ini" argument "cleanup". The variable "==" can of course not be
    included in the result. Similarly, "$(=ENV:...)", "$(=env:...)", and
    "$(=CONFIG:...)" are never included in the result.

  ACCESSING ENVIRONMENT AND CONFIG VARIABLES
    You can access environment variables with this "$(=ENV:...)" or this
    "$(=env:...)" notation. Example:

       path = $(=ENV:PATH)

    "path" now contains the content of your environment variable "PATH".

    The results of "$(=ENV:...)" and "$(=env:...)" are almost always the
    same. The difference is that the parser always leaves the value of
    "$(=ENV:...)" unchanged, but tries to expand the value of "$(=env:...)".
    For example, let's assume you have an environment variable "FOO" with
    the value "$(var)" and you write this in your INI file:

       var=hello!
       x=$(=ENV:FOO)
       y=$(=env:FOO)

    This results in "x" having the value "$(var)", while "y" has the value
    "hello!".

    You can access configuration variables of Perl's Config module with this
    "$(=CONFIG:...)" notation. Example:

      the archlib=$(=CONFIG:archlib)

    This gives the variable "the archlib" the value of $Config{archlib}.

    You can write something like "$([SEC]=ENV:FOO)"; this yields the same
    result as "$(=ENV:FOO)", provided that "[SEC]" exists, and an empty
    string if "[SEC]" does not exist. The same applies, of course, to
    "$([SEC]=env:FOO)" and "$([SEC]=CONFIG:FOO)".

    Note: In contrast to "$(=ENV:...)", there is no lower-case counterpart
    to "$(=CONFIG:...)", as this would not make sense.

  THE *TOCOPY* SECTION
   Default Behavior
    If specified, the method "parse_ini" copies the variables of the
    *tocopy* section (default name: "__TOCOPY__") to any other section when
    the INI file is read (default, this behavior can be changed by the
    constructor argument "global_mode"). For example this

       [__TOCOPY__]
       some var=some value
       section info=$(=)

       [A]

       [B]

    is exactly the same as this:

       [__TOCOPY__]
       some var=some
       section info=$(=)

       [A]
       some var=some
       section info=$(=)

       [B]
       some var=some
       section info=$(=)

    Of course, you can change or overwrite a variable copied from the
    "tocopy" section locally within a section at any time without any side
    effects. In this case, you can access the original value as follows:

       $([__TOCOPY__]some var)

    or - more generally - like this:

       $([$(=TO_CP_SEC)]some var)

    You can exclude variables with the argument "not_tocopy" from copying
    (methods "new" and "parse_ini"), but there is currently no notation to
    do this in the INI file.

    The *tocopy section* is optional. If it is specified, it must be the
    first section. By default, its name is "__TOCOPY__", this can be changed
    with the argument "tocopy_section" (methods "new" and "parse_ini"). You
    can omit the "[__TOCOPY__]" header and simply start your INI file with
    variable definitions. These then simply become the *tocopy section*. So
    this:

      [__TOCOPY__]
      a=this
      b=that

      [sec]
      x=y

    is exactly the same as this:

      a=this
      b=that

      [sec]
      x=y

    You can also add *tocopy* variables via the argument "tocopy_vars"
    (methods "new" and "parse_ini"), these are treated as if they were at
    the very beginning of the "tocopy" section.

   Global Mode
    If you specify the constructor argument "global_mode" with a *true*
    value, the variables of the *tocopy* section are not copied, but behave
    like global variables. Variables that you specify with the argument
    "not_tocopy" are not treated as global.

    Consequently, there is almost no difference in the referencing of
    variables if you use the global mode. The advantage of this mode is that
    you do not clutter your sections with unwanted variables.

    Example:

       [__TOCOPY__]
       a=this
       b=that

       [sec]
       x=y

    This would lead to this result by default:

       {
         __TOCOPY__ => {a => 'this', b => 'that'},
         sec        => {a => 'this', b => 'that', x => 'y'}
       }

    But in global mode the result is:

       {
         __TOCOPY__ => {a => 'this', b => 'that'},
         sec        => {x => 'y'}
       }

    To create a local copy of a global variable, use the assignment operator
    ":=" instead of a simple "=", since the latter can sometimes lead to
    undesirable results (see example below).

    NOTE: In some special cases, variables have different values in standard
    mode than in global mode. Example:

       section=$(=)
       x=GLOBAL
       x_val=$(x)

       [local-sec]
       var_1 := $(section)
       var_2 = $(section)

       x=LOCAL

       x_1 := $(x_val)
       x_2 = $(x_val)

    By default, you will get:

       {
         '__TOCOPY__' => {
                          'section' => '__TOCOPY__',
                          'x' => 'GLOBAL',
                          'x_val' => 'GLOBAL'
                         },
         'local-sec' => {
                         'section' => 'local-sec',
                         'var_1' => 'local-sec',
                         'var_2' => 'local-sec',
                         'x' => 'LOCAL',
                         'x_1' => 'LOCAL',
                         'x_2' => 'LOCAL',
                         'x_val' => 'LOCAL'
                        }
       }

    But in global mode, the result is:

       {
         '__TOCOPY__' => {
                          'section' => '__TOCOPY__',
                          'x' => 'GLOBAL',
                          'x_val' => 'GLOBAL'
                         },
         'local-sec' => {
                         'var_1' => 'local-sec',
                         'var_2' => '__TOCOPY__',
                         'x' => 'LOCAL',
                         'x_1' => 'LOCAL',
                         'x_2' => 'GLOBAL'
                   }
       }

    Note the different values for "var_2" and "x_2". When the assignment
    "x_1 := $(x_val)" is reached, the right-hand side is evaluated
    immediately, so that "$(x_val)" becomes "$(x)", which in turn leads to
    "LOCAL", since the definition of "x" in "[local-sec]" shadows the global
    "x".

    In contrast, the value of "x_2" is evaluated after the file has been
    completely read. This value is "$(x_val)" and the variable "x_val" was
    in turn previously evaluated in the global section and has the value
    "GLOBAL", which then becomes the value of "x_2".

    In standard mode, "x_val=$(x)" is copied to "[local-sec]" and "x_2" is
    given the value "LOCAL" due to the local definition of "x".

    A corresponding explanation applies to the different values of "var_2".

  FUNCTION CALLS
    In addition to variable references, function calls may be used in
    expanded values.

    There are two kinds of function calls:

    *   Built-in functions

          value = $(=& func, arg1, arg2, ...)

    *   User-defined functions

          value = $(=# func, arg1, arg2, ...)

    Function calls are evaluated during variable expansion. Arguments may
    contain variable references and nested function calls.

    Arguments are split before argument expansion, similar to GNU Make's
    "$(call ...)" function. Therefore commas introduced by later expansion
    do not create additional arguments.

    Example:

      [paths]
      comma = ,

      dir = $(=& catdir, foo, bar$(comma)baz)

    The second argument is expanded to "bar,baz", so the result becomes:

      foo/bar,baz

    rather than:

      foo/bar/baz

   Built-in Functions
    Built-in functions are called with "$(=& ...)".

    Example:

      [paths]
      root = /usr/local
      bin  = $(=& catdir, $(root), bin)

    Result:

      /usr/local/bin

    The built-in functions are provided by Config::INI::RefVars::Builtins.

    Function names are not expanded. Only function arguments are subject to
    variable expansion.

    Thus,

      path = $(=& catdir, foo, bar)

    is valid, whereas

      fn1 = cat
      fn2 = dir
      path = $(=& $(fn1)$(fn2), foo, bar)

    attempts to call a function literally named "$(fn1)$(fn2)" and therefore
    fails.

    Additional built-in functions can be registered via constructor argument
    "builtins", see also "Evaluating Arithmetic Expressions".

   User-defined Functions
    User-defined functions are defined with the "#=" assignment operator.

    Example:

      greet #= Hello $(1)!
      pair  #= $(1):$(2)

      [sec]
      msg1 = $(=# greet, World)
      msg2 = $(=# pair, foo, bar)

    Result:

      msg1 = Hello World!
      msg2 = foo:bar

    Function parameters are available as numeric variables:

      $(1)
      $(2)
      $(3)

    Missing parameters expand to the empty string.

    Example:

      triple #= $(1):$(2):$(3)

      [sec]
      x = $(=# triple, a, b)

    Result:

      x = a:b:

    Note: These numeric variables are always local within the function. They
    never overwrite a numeric variable defined outside the function, and a
    numeric variable defined outside the function is not visible within the
    function.

   Function Lookup
    User-defined functions are searched similarly to variables.

    For an unqualified call:

      $(=# func, arg1, arg2)

    the resolver searches:

    *   the current section

    *   the *tocopy* section

    *   the built-in function dispatcher

    Thus, a user-defined function can override a built-in function for "$(=#
    ...)" calls. The built-in function remains available via "$(=& ...)".

    Example:

      concat #= user:$(1):$(2)

      [sec]
      x = $(=# concat, a, b)
      y = $(=& concat, a, b)

    Result:

      x = user:a:b
      y = ab

   Qualified Function Calls
    A function from a specific section can be called explicitly:

      value = $(=# [section]func, arg1, arg2)

    This is analogous to qualified variable references:

      value = $([section]var)

    Example:

      fmt #= GLOBAL:$(1)

      [sec]
      fmt = not relevant
      fmt #= LOCAL:$(1)

      x = $(=# fmt, test)
      y = $(=# [__TOCOPY__]fmt, test)

    Result:

      x = LOCAL:test
      y = GLOBAL:test

    A qualified function call does not fall back to a built-in function if
    the specified section does not contain such a function.

    Note: the function name is interpreted literally and is not subject to
    variable expansion. Variable references are expanded only in the
    function arguments.

    Thus,

      myfunc #= myfunc:$(1)
      fn1 = my
      fn2 = func
      result = $(=# $(fn1)$(fn2), foo)

    attempts to call a function literally named "$(fn1)$(fn2)" and therefore
    fails.

   Function Scope
    Function bodies are expanded in the caller's scope.

    Example:

      fmt #= $(1):$(var)
      var = GLOBAL

      [sec]
      var = LOCAL
      x = $(=# fmt, test)

    Result:

      x = test:LOCAL

    A qualified variable reference may be used to force access to a variable
    from a specific section:

      fmt #= $(1):$([__TOCOPY__]var)

    Functions and variables use separate namespaces. Therefore this is
    valid:

      foo = value
      foo #= function:$(1)

    The variable "foo" is referenced with "$(foo)", while the function "foo"
    is called with "$(=# foo, ...)".

   Recursion
    Recursive user-defined function calls are detected and cause a fatal
    error.

    Example:

      recurse #= $(=# recurse)

      [sec]
      x = $(=# recurse)

    Produces an error similar to:

      recursive function '[__TOCOPY__]#=recurse' calls itself

  COMMENTS
    As said, if the first non-white character of a line is a ";" or a "#",
    then the line is a comment line.

       # This is a comment
       ; This is also a comment
           ;! a comment, but: avoid ";!" at the very beginning of a line!
       var = value ; this is not a comment but part of the value.

    Avoid ";!" at the very beginning of a line, otherwise you will get an
    error. The reason for this is that this sequence is reserved for future
    extensions. However, you can use it if you precede it with spaces.

    You cannot append a comment to the right of a variable definition, as
    your comment would otherwise become part of the variable value. But you
    can append a comment to the right of a header declaration:

       [section]  ; My fancy section

    Attention: if you do this, the comment must not contain a "]" character!

  METHODS
   new
    The constructor takes the following optional named arguments:

    "builtins"
        Optional. Argument for registering additional built-in functions.

        Example:

          my $cfg = Config::INI::RefVars->new(
                              builtins => {
                                             _uc => sub {
                                               return uc($_[0] // "");
                                             },
                                             _sprintf => sub {
                                               my $fmt = shift // return "";
                                               my $result;
                                               eval { $result = sprintf($fmt, @_); 1; } or
                                                 die("_sprintf: $@\n");
                                               return $result;
                                           },
                                          });

        The keys of the hash reference specify the function names. The
        values must be code references.

        Built-in functions are invoked using the "$(=& ...)" syntax:

          upper  = $(=& _uc,hello)
          string = $(=& _sprintf, <%s:%d>, a string, 27)

        The callback receives the expanded function arguments in @_. The
        callback's return value becomes the result of the function call.

        If a user-defined built-in has the same name as one of the
        predefined built-in functions, the user-defined implementation takes
        precedence.

        Exceptions thrown by a callback are propagated to the caller and
        abort parsing in the same way as errors raised by the predefined
        built-in functions.

        Naming convention: User-defined built-in functions may use any name,
        including the names of predefined built-in functions. If a
        user-defined built-in has the same name as a predefined one, the
        user-defined implementation takes precedence.

        To avoid accidental name clashes with future versions of this
        module, applications are encouraged to use function names containing
        at least one underscore ("_").

        This module guarantees that no predefined built-in function, present
        or future, will contain an underscore in its name.

        Examples:

          project_root
          is_release_build
          my_concat
          cfg_dir

        Using such names ensures that future versions of
        "Config::INI::RefVars" cannot introduce a conflicting predefined
        built-in function.

    "cmnt_vl"
        Optional, a boolean value. If this value is set to *true*, comments
        are permitted in variable lines. The comment character is a
        semicolon preceded by one or more spaces.

        Example:

           [section]
           var 1=val 1 ; comment
           var 2=val 2  ; ;  ; comment
           var 3=val 3; no comment
           var 4=val 4 $(); no comment

        After parsing, the "variables" method returns:

           section => {'var 1' => 'val 1',
                       'var 2' => 'val 2',
                       'var 3' => 'val 3; no comment',
                       'var 4' => 'val 4 ; no comment',
                      }

        Default is *false* ("undef").

    "global_mode"
        Optional, a boolean. Changes handling of the *tocopy* section, see
        section "Global Mode". See also the accessor method of the same
        name.

    "not_tocopy"
        Optional, a reference to a hash or an array of strings. The hash
        keys or array entries specify a list of variables that should not be
        copied from the *tocopy* section to the other sections. It does not
        matter whether these variables actually occur in the *tocopy*
        section or not.

        Default is "undef".

    "separator"
        Optional, a string. If specified, an alternative notation can be
        used for referencing variables in another section. Example:

           my $obj = Config::INI::RefVars->new(separator => '::');

        Then you can write:

            [A]
            y=27

            [B]
            a var=$(A::y)

        This gives the variable "a var" the value 27.

        The following characters are permitted for "separator":

           #!%&',./:~\

        See also the accessor method of the same name.

    "tocopy_section"
        Optional, a string. Specifies a different name for the *tocopy*
        section. Default is "__TOCOPY__". See accessor "tocopy_section".

    "tocopy_vars"
        Optional, a hash reference. If specified, its keys become variables
        of the *tocopy* section, the hash values become the corresponding
        variable values. This allows you to specify variables that you
        cannot specify in the INI file, e.g. variables with a "=" in the
        name.

        Keys with "=" or ";" as the first character are not permitted.

        Default is "undef".

    "varname_chk_re"
        Optional, a compiled regex. If specified, each variable name defined
        in the INI source must match this regex.

        Example:

           my $obj = Config::INI::RefVars->new(varname_chk_re => qr/^[A-Z]/);
           my $src = <<'EOT';
              [the section]
              A=the value
              xYZ=123
              Z1=z2
              Y=
           EOT
          $obj->parse_ini(src => $src);

        This will result in an exception with the message "'xYZ': var name
        does not match varname_chk_re".

   current_tocopy_section
    Returns the name of the section *tocopy* that was used the last time
    "parse_ini" was called. Please note that the section does not have to be
    present in the data.

    See also method "tocopy_section".

   global_mode
    Returns a boolean value indicating whether the global mode is activated
    or not. See constructor argument of the same name, see also section
    "Global Mode".

   parse_ini
    Parses an INI source. The method takes the following optional arguments:

    "src"
        Mandatory, a string or an array reference. This specifies the source
        to parse. If it is a character string that does not contain a
        newline character, it is treated as the name of an INI file.
        Otherwise, its content is parsed directly.

    "cleanup"
        Optional, a boolean. If this value is set to *false*, variables with
        a "=" in their name are not removed from the resulting hash that is
        returned by the "variables" method. But in global mode, most of this
        variables will not be contained, see section "Global Mode".

        Default is 1 (*true)*

    "tocopy_section"
        Optional, a string. Specifies a different name for the *tocopy*
        section for this run only. The previous value is restored before the
        method returns. Default is the string returned by accessor
        "tocopy_section".

        See constructor argument of the same name.

    "tocopy_vars"
        Optional, overwrites the corresponding setting saved in the object
        for this run only. The previous setting is restored before the
        method returns.

        See constructor argument of the same name.

    "not_tocopy"
        Optional, overwrites the corresponding setting saved in the object
        for this run only. The previous setting is restored before the
        method returns.

        See constructor argument of the same name.

    "src_name"
        Optional, overwrites the corresponding setting saved in the object
        for this run only. The previous setting is restored before the
        method returns.

        See constructor argument of the same name, see also the accessor of
        the same name.

   sections
    Returns a reference to an array of section names from the INI source, in
    the order in which they appear there.

   sections_h
    Returns a reference to a hash whose keys are the section names from the
    INI source, the values are the corresponding indices in the array
    returned by "sections".

   separator
    Returns the value that was passed to the constructor via the argument of
    the same name, or "undef" .

   src_name
    Returns the name of the INI source (file name that you have passed to
    "parse_ini" via the argument "src", or the one that you have passed via
    the argument "src_name", or ""INI data"", see section "Variables in
    relation to the source".

   tocopy_section
    Returns the name of the *tocopy* section that will be used as the
    default for the next call to "parse_ini".

    See also method "current_tocopy_section".

   variables
    Returns a reference to a hash of hashes. The keys are the section names,
    each value is the corresponding hash of variables (key: variable name,
    value: variable value). By default, variables with a "=" in their name
    are not included; this can be changed with the "cleanup" argument.

  PITFALLS
   Method "sections" vs. "sections_h"
    In most cases, the keys in the hash returned by "variables" are the same
    as the keys in the hash returned by the "sections_h" method and the
    entries in the array returned by the "sections" method. In special
    cases, however, there may be a difference with regard to the *tocopy*
    section. Example:

       [A]
       a=1

       [B]
       b=2

    If you parse this INI source like this:

      my $obj = Config::INI::RefVars->new();
      $obj->parse_ini(src => $src, tocopy_vars => {'foo' => 'xyz'});

    then the "variables" method returns this:

      {
        'A' => {
                'a' => '1',
                'foo' => 'xyz'
               },
        'B' => {
                'b' => '2',
                'foo' => 'xyz'
               },
        '__TOCOPY__' => {
                         'foo' => 'xyz'
                        }
      }

    but "sections_h" returns

       { 'A' => '0',
         'B' => '1' }

    and "sections" returns

       ['A', 'B']

    No "__TOCOPY__". The reason for this is that the return values of
    "sections_h" and "sections" refer to what is contained in the source,
    and in this case "__TOCOPY__" is not contained in the source, but comes
    from a method argument.

   Separator in Variable Names
       my $cfg = Config::INI::RefVars->new(separator => "/");

       my $ini =<<'INI';
        [FOO]
        var=abcde

        [BAR]
        FOO/var=my var in section BAR
        a=$(FOO/var)
        b=$(BAR/FOO/var)
       INI

    By specifying the "separator" argument, qualified variable references
    use the form "$(SECTION/VARIABLE)".

    Section "[BAR]" defines a variable named "FOO/var". This is a valid
    variable name, even though it contains the configured separator.

    The resulting data structure is:

       {
          'FOO' => {
                     'var' => 'abcde'
                   },
          'BAR' => {
                     'b' => 'my var in section BAR',
                     'a' => 'abcde',
                     'FOO/var' => 'my var in section BAR'
                   }
       }

    In this case, "FOO/var" can only be referenced in the qualified form.

   Regular Expressions: Groups
    Currently, there is no access to the contents of capturing groups.
    However, you may still want to use non-capturing groups. In this case,
    be aware that you cannot use them directly in the regular expression,
    since the closing parenthesis will confuse the parser. Therefore, the
    following will not work:

      [WRONG]
      a = $(=& m, bb, ^(?:a|b)b$)

    Instead, use a helper variable, e.g.:

      [RIGHT]
      regex = (?:a|b)b
      a = $(=& m, bb, ^$(regex)$)

  EXAMPLES
   Reading DHCP Server INI files
    You can parse INI files as described here $(section\name) syntax for INI
    file variables
    <https://www.dhcpserver.de/cms/ini_file_reference/special/sectionname-sy
    ntax-for-ini-file-variables/> as follows:

       my $obj = Config::INI::RefVars->new(separator      => "\\",
                                           cmnt_vl        => 1,
                                           tocopy_section => 'Settings',
                                           global_mode    => 1);
       my $src = <<'EOT';
         [Settings]
         BaseDir="d:\dhcpsrv" ; dhcpsrv.exe resides here
         IPBIND_1=192.168.17.2
         IPPOOL_1=$(Settings\IPBIND_1)-50
         AssociateBindsToPools=1
         Trace=1
         TraceFile="$(BaseDir)\dhcptrc.txt" ; trace file

         [DNS-Settings]
         EnableDNS=1

         [General]
         SUBNETMASK=255.255.255.0
         DNS_1=$(IPBIND_1)

         [TFTP-Settings]
         EnableTFTP=1
         Root="$(BaseDir)\wwwroot" ; use wwwroot for http and tftp

         [HTTP-Settings]
         EnableHTTP=1
         Root="$(BaseDir)\wwwroot" ; use wwwroot for http and tftp
       EOT
       $obj->parse_ini(src => $src);

   Evaluating Arithmetic Expressions
    There is no built-in arithmetic. However, if you need to evaluate
    arithmetic expressions in your INI file, it is simple to add such a
    feature, e.g.:

      use strict;
      use warnings;

      use Config::INI::RefVars;
      use Math::Expression::Evaluator;

      my $cfg = Config::INI::RefVars->new(
        builtins => {
          my_calculator => sub {
            die("my_calculator: needs exactly 1 arg") unless @_ == 1;

            my $m = Math::Expression::Evaluator->new;
            my $result;

            eval { $result = $m->parse($_[0])->val(); 1 }
              or die("my_calculator: $@");

            return $result;
          },
        },
      );

      my $ini = <<'INI';
      [sec]
      val = 3
      result = $(=& my_calculator, 2 + $(val))
      INI

      print($cfg->parse_ini(src => $ini)->variables->{sec}{result}, "\n");

    This will print 5.

ERROR HANDLING
    Most parsing and expansion errors are reported by throwing an exception.

    Examples include:

    *   syntax errors

    *   undefined variables

    *   unknown functions

    *   recursive variable references

    *   recursive function calls

    If parse_ini() dies, the object may be left in an inconsistent state.

    Applications should treat the object as unusable after a parsing error
    and create a new object before attempting another parse operation.

SEE ALSO
    $(section\name) syntax for INI file variables
    <https://www.dhcpserver.de/cms/ini_file_reference/special/sectionname-sy
    ntax-for-ini-file-variables/>

    This one allows also referencing variables: Config::IOD::Reader.

    Other modules handling INI files:

    Config::INI, Config::INI::Tiny, Config::IniFiles, Config::Tiny and many
    more.

    Remark: the built-in functions are provided by
    Config::INI::RefVars::Builtins.

AUTHOR
    #AUTHOR#, "<451 at gmx.eu>"

BUGS
    Please report any bugs or feature requests to "bug-config-ini-accvars at
    rt.cpan.org", or through the web interface at
    <https://rt.cpan.org/NoAuth/ReportBug.html?Queue=Config-INI-RefVars>. I
    will be notified, and then you'll automatically be notified of progress
    on your bug as I make changes.

SUPPORT
    You can find documentation for this module with the perldoc command.

        perldoc Config::INI::RefVars

    You can also look for information at:

    *   GitHub Issue (preferred for issues)

        <https://github.com/AAHAZRED/perl-Config-INI-RefVars/issues>

    *   RT: CPAN's request tracker (you may report bugs also here)

        <https://rt.cpan.org/NoAuth/Bugs.html?Dist=Config-INI-RefVars>

    *   Search CPAN

        <https://metacpan.org/release/Config-INI-RefVars>

    *   GitHub Repository

        <https://github.com/AAHAZRED/perl-Config-INI-RefVars>

LICENSE AND COPYRIGHT
    This software is copyright (c) 2026 by #AUTHOR#.

    This is free software; you can redistribute it and/or modify it under
    the same terms as the Perl 5 programming language system itself.

