diff --git a/CHANGELOG.md b/CHANGELOG.md index fba9864..6a5f27b 100644 --- a/CHANGELOG.md +++ b/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 diff --git a/README.md b/README.md index f308e1f..fde6de2 100644 --- a/README.md +++ b/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"` diff --git a/dub.json b/dub.json index 9633452..15b5cec 100644 --- a/dub.json +++ b/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" } } \ No newline at end of file diff --git a/dub.selections.json b/dub.selections.json index 7599e9d..ed6e7af 100644 --- a/dub.selections.json +++ b/dub.selections.json @@ -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" } } diff --git a/examples/comments.conf b/examples/comments.conf index 0a9a588..c9952d3 100644 --- a/examples/comments.conf +++ b/examples/comments.conf @@ -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 \ No newline at end of file +parameter10 => '"value10"' // Quotes inside +parameter11 => ; empty value diff --git a/examples/sections.conf b/examples/sections.conf index acaca5f..fd8ed63 100644 --- a/examples/sections.conf +++ b/examples/sections.conf @@ -19,4 +19,4 @@ parameter4 = value10 [_section] # Creating the new section parameter1 = value11 -parameter2 = value12 \ No newline at end of file +parameter2 = value12 diff --git a/examples/simple.conf b/examples/simple.conf index 4700094..21b62b3 100644 --- a/examples/simple.conf +++ b/examples/simple.conf @@ -13,4 +13,5 @@ parameter-10 =>value10 parameter11 = value11 -parameter12_ => value12 \ No newline at end of file +parameter12_ => value12 +parameter13 = diff --git a/img/matches.png b/img/matches.png index 9ca06cd..8a61386 100644 Binary files a/img/matches.png and b/img/matches.png differ diff --git a/source/readconf.d b/source/readconf.d index 33fc0a6..ce464b3 100644 --- a/source/readconf.d +++ b/source/readconf.d @@ -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][0] == '\"') - group = GROUP_VALUE_2; - else if (match[group][0] == '\'') - group = GROUP_VALUE_3; + 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]; } } diff --git a/tests/settings.conf b/tests/settings.conf index 6d4fb28..5ba73d4 100644 --- a/tests/settings.conf +++ b/tests/settings.conf @@ -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 diff --git a/tests/test.d b/tests/test.d index a12c32a..c00571d 100644 --- a/tests/test.d +++ b/tests/test.d @@ -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");