D-Programming-Language/phobos — pull request #449 by bioinfornatics (2012-02-22 15:08:32+00:00)
Title: [RFC] ini Parser

Dear, i have wrote a ini parser using range as BidirectionalRange and maybe Infinite RandomAccessRange.

section class has:
- empty, front and popFront() that InputRange requires
- save() that ForwardRange requires
- opIndex() that RandomAccessRange requires
- the value of empty to be known at compile time as false

Example of use:
```d
import std.string;
import std.stdio;
import std.ini;

void main( ){
writeln( "0 - Starting test" );
IniFile tester = open("myConfig.ini");
writeln( "Ini file loaded" );
writefln( "1 - Name: %s, level: %d", tester.name, tester.level);
writefln( "2 - childs:\n%s,", tester.childs );
writefln( "3 - object is null: %s", tester is null );
writefln( "4 - number of section: %d", tester.length );
writefln( "5 - sectionA: %s", tester.get("sectionA") );
writefln( "6 - sectionA.param1: %s", tester.get("sectionA")["param1"] );
writefln( "7 - first section:\n%s", tester.front );
writefln( "8 - last section:\n%s", tester.back );
writeln( "9 - popfront" );
tester.popFront();
writefln( "10 - first section:\n%s", tester.front );
tester.popBack();
writefln( "11 - last section:\n%s", tester.back );
writeln( "12 - create a section" );
Section toAdd = new Section( "sectionD", tester.level + 1);
writeln( "13 - append pair key/value to this section: D = is fun" );
toAdd["D"] = "is fun";
writeln( "14 - Append the newest section to main section" );
tester.addChild( toAdd );
writeln( "15 - show the section added" );
writeln( tester.get("sectionD") );
writefln( "16 - show all childs:\n%s,", tester.childs );
writeln( "17 - shrink for remove unused space");
toAdd.shrink;
writeln( "18 - write current section object to a file" );
File inisavedFile = File( "soEasy.ini", "w");
inisavedFile.write( tester );
inisavedFile.close();
}

```

Output

```bash
$ ./test_ini
0 - Starting test
Ini file loaded
1 - Name: root, level: 0
2 - childs:
[[sectionA]
param1=value1
param2=value2
[[subSectionA]]
param1sub=value1sub
, [sectionB]
param3=value3
param4=value4
, [sectionC]
param5=value5
param6=value6
],
3 - object is null: false
4 - number of section: 3
5 - sectionA: [sectionA]
param1=value1
param2=value2
[[subSectionA]]
param1sub=value1sub

6 - sectionA.param1: value1
7 - first section:
[sectionA]
param1=value1
param2=value2
[[subSectionA]]
param1sub=value1sub

8 - last section:
[sectionC]
param5=value5
param6=value6

9 - popfront
10 - first section:
[sectionB]
param3=value3
param4=value4

11 - last section:
[sectionB]
param3=value3
param4=value4

12 - create a section
13 - append pair key/value to this section: D = is fun
14 - Append the newest section to main section
15 - show the section added
[sectionD]
D=is fun

16 - show all childs:
[[sectionB]
param3=value3
param4=value4
, [sectionD]
D=is fun
, null, null, null, null],
17 - shrink for remove unused space
18 - write current section object to a file

$ cat soEasy.ini
[sectionB]
param3=value3
param4=value4
[sectionD]
D=is fun