From de3690c94e609bb641529423299a9cc6120fa70f Mon Sep 17 00:00:00 2001 From: Alexander Date: Sun, 26 Mar 2023 20:16:46 +0300 Subject: [PATCH] v0.3.0-dev.1 --- CHANGELOG.md | 18 ++++++++++--- source/readconf.d | 65 ++++++++++++++++++++++++++++++++++++++++++----- tests/test.d | 25 ++++++++++-------- 3 files changed, 87 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b8027f7..e549c64 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,23 @@ # Changelog -## [0.2.0]() - -26.03.2023 +## [v0.2.0](https://git.zhirov.kz/dlang/readconf/compare/v0.1.1...v0.2.0) (2023.03.26) ### New - Adding sections support - Taking into account spaces and tabs to separate the parameter, value and comment - Added aliases to convenient parameter access to the value + +## [v0.1.1](https://git.zhirov.kz/dlang/readconf/compare/v0.1.0...v0.1.1) (2023.03.24) + +### Bug fixes + +- Checking empty keys +- Reading an expression in quotation marks + +## [v0.1.0](https://git.zhirov.kz/dlang/readconf/commits/6409917cbe6a287db73fe3eea4bccaadf00379e7) (2023.03.23) + +### The first stable working release + +- The parameters are separated by `=` or `=>` +- The ability to comment lines through delimiters `;`, `#`, `//` diff --git a/source/readconf.d b/source/readconf.d index 6899641..ecb71ee 100644 --- a/source/readconf.d +++ b/source/readconf.d @@ -27,7 +27,7 @@ private: static Config config; string path; bool readed = false; - ConfigSection[string] sections; + ConfigFile[string] configs; const string pattern = "^( |\\t)*(((\\w(\\w|-)+)(( |\\t)*(=>|=){1}" ~ "( |\\t)*)(?!\\/(\\/|\\*))(([^ >\"'=\\n\\t#;].*?)|(\"(.+)\")" @@ -37,7 +37,7 @@ private: /** * Reading the configuration file */ - bool readConfig() + bool readConfig(const string configName) { File configuration; @@ -49,6 +49,9 @@ private: return false; } + if (configName !in this.configs) + this.configs[configName] = ConfigFile(configName); + auto regular = regex(this.pattern, "m"); // reading from the main section @@ -79,10 +82,12 @@ private: else if (match[group][0] == '\'') group = GROUP_VALUE_3; - if (sectionName !in this.sections) - this.sections[sectionName] = ConfigSection(sectionName); + this.configs[configName].add(sectionName, ConfigParameter(match[GROUP_PROPERTY], match[group])); + + // if (sectionName !in this.sections) + // this.sections[sectionName] = ConfigSection(sectionName); - this.sections[sectionName].add(ConfigParameter(match[GROUP_PROPERTY], match[group])); + // this.sections[sectionName].add(ConfigParameter(match[GROUP_PROPERTY], match[group])); } } @@ -92,6 +97,7 @@ private: } catch (Exception e) { Log.msg.warning("Unable to close the configuration file " ~ this.path); Log.msg.error(e); + this.configs.remove(configName); this.readed = false; } @@ -118,14 +124,51 @@ public: * Params: * path = the path to the configuration file */ - bool read(string path) + bool read(string path, string configName = "") { this.path = path; if (!path.exists) throw new Exception("The configuration file does not exist: " ~ path); - return readConfig(); + if (configName.length == 0) + configName = path.baseName(); + if (configName in configs) + throw new Exception("The configuration file with this name has already been read"); + return readConfig(configName); } + /** + * Get the section + * Params: + * section = section name (default main "[]") + */ + @property ConfigFile configFile(string configName = "") + { + if (configName.length == 0) + { + if (configs.length == 1) + return configs[configs.byKey.front]; + else + throw new Exception("You must explicitly specify the name of the configuration file"); + } + + return configName in configs ? configs[configName] : ConfigFile(); + } + + /** + * Config file + * + * Get the config file + * Params: + * configName = config name (by default the name of the configuration file) + */ + alias cf = configFile; +} + +struct ConfigFile +{ + private string name = "[]"; + private ConfigSection[string] sections; + /** * Get the section * Params: @@ -144,6 +187,14 @@ public: * section = section name (default main "[]") */ alias sn = sectionName; + + private void add(string sectionName, ConfigParameter parameter) + { + if (sectionName !in this.sections) + this.sections[sectionName] = ConfigSection(sectionName); + + this.sections[sectionName].add(parameter); + } } struct ConfigSection diff --git a/tests/test.d b/tests/test.d index 60e75be..ff4bb36 100644 --- a/tests/test.d +++ b/tests/test.d @@ -3,18 +3,21 @@ import readconf; unittest { rc.read("./tests/settings.conf"); + rc.read("./tests/settings.conf", "new"); - assert(rc.sn.key("value1") == "text without quotes"); - assert(rc.sn.key("value2") == "Yes!"); - assert(rc.sn.key("value3") == "value in apostrophes"); - assert(rc.sn.key("value4") == "1000"); - assert(rc.sn.key("value5") == "0.000"); - assert(rc.sn.key("value7") == "//path"); - assert(rc.sn.key("value8") == "\"Hey!\""); - assert(rc.sn("part2").key("value1") == "this value will be in the new section"); - assert(rc.sn("part2").key("value3") == "good value!"); - assert(rc.sn("part3").key("value1") == "-2"); - assert(rc.sn("part3").key("value3") == "100"); + assert(rc.cf("settings.conf").sn.key("value1") == "text without quotes"); + assert(rc.cf("settings.conf").sn.key("value2") == "Yes!"); + assert(rc.cf("settings.conf").sn.key("value3") == "value in apostrophes"); + assert(rc.cf("settings.conf").sn.key("value4") == "1000"); + assert(rc.cf("settings.conf").sn.key("value5") == "0.000"); + assert(rc.cf("settings.conf").sn.key("value7") == "//path"); + assert(rc.cf("settings.conf").sn.key("value8") == "\"Hey!\""); + assert(rc.cf("settings.conf").sn("part2").key("value1") == "this value will be in the new section"); + assert(rc.cf("settings.conf").sn("part2").key("value3") == "good value!"); + assert(rc.cf("settings.conf").sn("part3").key("value1") == "-2"); + assert(rc.cf("settings.conf").sn("part3").key("value3") == "100"); + + assert(rc.cf("new").sn("part3").key("value3") == "100"); } // void main()