The task is to read a configuration file in standard configuration file format,
and set variables accordingly.

For this task, we have a configuration file as follows:

# This is a configuration file in standard configuration file format
#
# Lines beginning with a hash or a semicolon are ignored by the application
# program. Blank lines are also ignored by the application program.

# This is the fullname parameter
FULLNAME Foo Barber

# This is a favourite fruit
FAVOURITEFRUIT banana

# This is a boolean that should be set
NEEDSPEELING

# This boolean is commented out
; SEEDSREMOVED

# Configuration option names are not case sensitive, but configuration parameter
# data is case sensitive and may be preserved by the application program.

# An optional equals sign can be used to separate configuration parameter data
# from the option name. This is dropped by the parser. 

# A configuration option may take multiple parameters separated by commas.
# Leading and trailing whitespace around parameter names and parameter data fields
# are ignored by the application program.

OTHERFAMILY Rhu Barber, Harry Barber



For the task we need to set four variables according to the configuration entries as follows:

fullname = Foo Barber
favouritefruit = banana
needspeeling = true
seedsremoved = false


We also have an option that contains multiple parameters. These may be stored in an array.

 otherfamily(1) = Rhu Barber
 otherfamily(2) = Harry Barber


Related tasks
 Update a configuration file


import std.stdio, std.string, std.conv, std.regex, std.getopt;
 
enum VarName(alias var) = var.stringof.toUpper;
 
void setOpt(alias Var)(in string line) {
    auto m = match(line, regex(`^` ~ VarName!Var ~ `(\s+(.*))?`));
    if (!m.empty) {
        static if (is(typeof(Var) == string))
            Var = m.captures.length > 2 ? m.captures[2] : "";
        static if (is(typeof(Var) == bool))
            Var = true;
        static if (is(typeof(Var) == int))
            Var = m.captures.length > 2 ? to!int(m.captures[2]) : 0;
    }
}
 
void main(in string[] args) {
    string fullName, favouriteFruit, otherFamily;
    bool needsPeeling, seedsRemoved; // Default false.
    auto f = "readcfg.txt".File;
 
    foreach (line; f.byLine) {
        auto opt = line.strip.idup;
        setOpt!fullName(opt);
        setOpt!favouriteFruit(opt);
        setOpt!needsPeeling(opt);
        setOpt!seedsRemoved(opt);
        setOpt!otherFamily(opt);
    }
 
    writefln("%14s = %s", VarName!fullName, fullName);
    writefln("%14s = %s", VarName!favouriteFruit, favouriteFruit);
    writefln("%14s = %s", VarName!needsPeeling, needsPeeling);
    writefln("%14s = %s", VarName!seedsRemoved, seedsRemoved);
    writefln("%14s = %s", VarName!otherFamily, otherFamily);
}