v0.4.0 #5
11
CHANGELOG.md
11
CHANGELOG.md
|
@ -1,5 +1,16 @@
|
|||
# Changelog
|
||||
|
||||
## [v0.4.0](https://git.zhirov.kz/dlang/readconf/compare/v0.3.1...v0.4.0) (2023.06.07)
|
||||
|
||||
### New
|
||||
|
||||
- Reading empty parameter values
|
||||
- Parameter name as a single character
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- Generating an exception when accessing a non-existent section
|
||||
|
||||
## [v0.3.1](https://git.zhirov.kz/dlang/readconf/compare/v0.3.0...v0.3.1) (2023.04.30)
|
||||
|
||||
- Windows OS support
|
||||
|
|
17
README.md
17
README.md
|
@ -34,15 +34,15 @@ void main()
|
|||
{
|
||||
rc.read("./tests/settings.conf");
|
||||
|
||||
foreach (key, param; rc.sn.keys())
|
||||
foreach (key, param; rc.cf.sn.keys())
|
||||
writefln("%s => %s", key, param);
|
||||
|
||||
writeln(rc.sn.key("value1"));
|
||||
writeln(rc.cf.sn.key("value1"));
|
||||
|
||||
foreach (key, param; rc.sn("part2").keys())
|
||||
foreach (key, param; rc.cf.sn("part2").keys())
|
||||
writefln("%s => %s", key, param);
|
||||
|
||||
writeln(rc["part2"]["value1"]);
|
||||
writeln(rc[]["part2"]["value1"]);
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -54,6 +54,7 @@ value2 => Yes!
|
|||
value3 => value in apostrophes
|
||||
value4 => 1000
|
||||
value5 => 0.000
|
||||
value6 =>
|
||||
value7 => //path
|
||||
value8 => "Hey!"
|
||||
text without quotes
|
||||
|
@ -68,14 +69,14 @@ The unittests provide [examples](examples/) of configuration files and the `sett
|
|||
|
||||
```sh
|
||||
Running bin/readconf-test-unittest
|
||||
✓ test __unittest_L111_C1
|
||||
✓ test __unittest_L26_C1
|
||||
✓ test __unittest_L52_C1
|
||||
✓ test __unittest_L4_C1
|
||||
✓ test __unittest_L106_C1
|
||||
✓ test __unittest_L25_C1
|
||||
✓ test __unittest_L51_C1
|
||||
|
||||
Summary: 4 passed, 0 failed in 7 ms
|
||||
```
|
||||
|
||||
## DUB
|
||||
|
||||
Add a dependency on `"readconf": "~>0.3.1"`
|
||||
Add a dependency on `"readconf": "~>0.4.0"`
|
||||
|
|
12
dub.json
12
dub.json
|
@ -17,22 +17,14 @@
|
|||
"name": "unittest",
|
||||
"targetPath": "bin",
|
||||
"dependencies": {
|
||||
"silly": "~>1.1.1"
|
||||
"silly": "~>1.2.0-dev.2"
|
||||
},
|
||||
"importPaths": ["source","tests"],
|
||||
"sourcePaths": ["tests"]
|
||||
},
|
||||
{
|
||||
"name": "executable",
|
||||
"targetType": "executable",
|
||||
"targetPath": "bin",
|
||||
"targetName": "app",
|
||||
"importPaths": ["source","tests"],
|
||||
"sourcePaths": ["tests"]
|
||||
}
|
||||
],
|
||||
"targetName": "readconf",
|
||||
"dependencies": {
|
||||
"singlog": "~>0.3.0"
|
||||
"singlog": "~>0.4.0"
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
"fileVersion": 1,
|
||||
"versions": {
|
||||
"datefmt": "1.0.4",
|
||||
"silly": "1.1.1",
|
||||
"singlog": "0.3.0"
|
||||
"silly": "1.2.0-dev.2",
|
||||
"singlog": "0.4.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,8 @@ parameter3 => value3 // This will be a comment
|
|||
parameter4 => value4 /* This will be a comment
|
||||
parameter5 => value5;This will not be a comment
|
||||
parameter6 => value6// This will also be a whole value
|
||||
parameter7 => //value7 ;The value will not be read
|
||||
parameter7 => //value7 ;The value will be read as empty value
|
||||
parameter8 => "//value8" # Now the value is correctly
|
||||
parameter9 => ';value9' // The value is correctly too
|
||||
parameter10 => '"value10"' // Quotes inside
|
||||
parameter11 => ; empty value
|
||||
|
|
|
@ -14,3 +14,4 @@ parameter11 = value11
|
|||
|
||||
|
||||
parameter12_ => value12
|
||||
parameter13 =
|
||||
|
|
BIN
img/matches.png
BIN
img/matches.png
Binary file not shown.
Before Width: | Height: | Size: 137 KiB After Width: | Height: | Size: 119 KiB |
|
@ -21,12 +21,12 @@ class Config
|
|||
private:
|
||||
enum {
|
||||
GROUP_PARAMETER = 4,
|
||||
GROUP_VALUE_1 = 11, // string
|
||||
GROUP_VALUE_2 = 14, // "strin"
|
||||
GROUP_VALUE_3 = 16, // 'string'
|
||||
GROUP_SECTION_OTHER_OUTER = 17, // [string]
|
||||
GROUP_SECTION_OTHER_INNER = 18, // string
|
||||
GROUP_SECTION_MAIN = 20, // []
|
||||
GROUP_VALUE_1 = 12, // string
|
||||
GROUP_VALUE_2 = 15, // "strin"
|
||||
GROUP_VALUE_3 = 17, // 'string'
|
||||
GROUP_SECTION_OTHER_OUTER = 19, // [string]
|
||||
GROUP_SECTION_OTHER_INNER = 20, // string
|
||||
GROUP_SECTION_MAIN = 23, // []
|
||||
}
|
||||
|
||||
static Config config;
|
||||
|
@ -34,9 +34,9 @@ private:
|
|||
bool readed = false;
|
||||
ConfigFile[string] configs;
|
||||
|
||||
const string pattern = "^( |\\t)*(((\\w(\\w|-)+)(( |\\t)*(=>|=){1}"
|
||||
~ "( |\\t)*)(?!\\/(\\/|\\*))(([^ >\"'=\\n\\t#;].*?)|(\"(.+)\")"
|
||||
~ "|('(.+)')){1})|(\\[(\\w(\\w|-)+)\\])|(\\[\\]))( |\\t)*"
|
||||
const string pattern = "^( |\\t)*((((\\w(\\w|-)?)+)(( |\\t)*(=>|=){1}"
|
||||
~ "( |\\t)*)(?!\\/(\\/|\\*))(([^ >\"'=\\n\\t#;].*?)|(\"(.+)?\")"
|
||||
~ "|('(.+)?')|()){1})|(\\[((\\w(\\w|-)?)+)\\])|(\\[\\]))( |\\t)*"
|
||||
~ "(( |\\t)(#|;|\\/\\/|\\/\\*).*)?$";
|
||||
|
||||
/**
|
||||
|
@ -84,10 +84,12 @@ private:
|
|||
|
||||
int group = GROUP_VALUE_1;
|
||||
|
||||
if (match[group].length) {
|
||||
if (match[group][0] == '\"')
|
||||
group = GROUP_VALUE_2;
|
||||
else if (match[group][0] == '\'')
|
||||
group = GROUP_VALUE_3;
|
||||
}
|
||||
|
||||
this.configs[configName].add(sectionName, ConfigParameter(match[GROUP_PARAMETER], match[group]));
|
||||
}
|
||||
|
@ -207,7 +209,10 @@ struct ConfigFile
|
|||
return sections[sections.byKey.front];
|
||||
if (section.length == 0)
|
||||
section = mainSection;
|
||||
return section in sections ? sections[section] : ConfigSection(section);
|
||||
if (section !in sections)
|
||||
throw new Exception("The selected section does not exist");
|
||||
|
||||
return sections[section];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -234,7 +239,10 @@ struct ConfigFile
|
|||
return sections[sections.byKey.front];
|
||||
if (section.length == 0)
|
||||
section = mainSection;
|
||||
return section in sections ? sections[section] : ConfigSection(section);
|
||||
if (section !in sections)
|
||||
throw new Exception("The selected section does not exist");
|
||||
|
||||
return sections[section];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,8 +5,8 @@ value2=>"value in quotation marks"
|
|||
value3=>'value in apostrophes' ; and here is the first comment
|
||||
value4 => 1000 // free space in spaces and tabs
|
||||
value5 => 0.000 /* different form of commenting
|
||||
value6 = // the string will not be read because the parameter value is missing
|
||||
value7 = '' ; limiting empty characters will also not be taken into account
|
||||
value6 = // the string will be read as empty value
|
||||
value7 = '' ; limiting empty characters will also be taken into account
|
||||
[part2] ; a new section!
|
||||
value1 = this value will be in the new section
|
||||
value 2 = 200 ; The parameter name is incorrect
|
||||
|
|
|
@ -20,6 +20,7 @@ unittest
|
|||
assert(mainSection["parameter-10"] == "value10");
|
||||
assert(mainSection.key("parameter11") == "value11");
|
||||
assert(mainSection["parameter12_"] == "value12");
|
||||
assert(mainSection["parameter13"].empty);
|
||||
}
|
||||
|
||||
unittest
|
||||
|
@ -98,9 +99,13 @@ unittest
|
|||
assert(comConMaiSec["parameter4"] == "value4");
|
||||
assert(comConMaiSec["parameter5"] == "value5;This will not be a comment");
|
||||
assert(comConMaiSec["parameter6"] == "value6// This will also be a whole value");
|
||||
assert(comConMaiSec["parameter7"] == "");
|
||||
assert(comConMaiSec["parameter7"].empty);
|
||||
assert(comConMaiSec["parameter8"] == "//value8");
|
||||
assert(comConMaiSec["parameter9"] == ";value9");
|
||||
assert(comConMaiSec["parameter10"] == "\"value10\"");
|
||||
assert(comConMaiSec["parameter11"] == "");
|
||||
assert(comConMaiSec["parameter11"].empty);
|
||||
}
|
||||
|
||||
unittest
|
||||
|
@ -112,6 +117,7 @@ unittest
|
|||
assert(rc.cf.sn.key("value3") == "value in apostrophes");
|
||||
assert(rc[][]["value4"] == "1000");
|
||||
assert(rc.cf.sn["value5"] == "0.000");
|
||||
assert(rc.cf.sn["value6"].empty);
|
||||
assert(rc[][].key("value7") == "//path");
|
||||
assert(rc.cf.sn.key("value8") == "\"Hey!\"");
|
||||
assert(rc[]["part2"]["value1"] == "this value will be in the new section");
|
||||
|
|
Loading…
Reference in New Issue