v0.0.1
This commit is contained in:
commit
f1daabbc94
|
@ -0,0 +1,4 @@
|
||||||
|
.vscode
|
||||||
|
.dub
|
||||||
|
*.o
|
||||||
|
lib
|
|
@ -0,0 +1,65 @@
|
||||||
|
# readconf
|
||||||
|
|
||||||
|
Singleton for reading the configuration file required for your program.
|
||||||
|
|
||||||
|
The `settings.conf` file:
|
||||||
|
|
||||||
|
```conf
|
||||||
|
Such a line will not be read
|
||||||
|
value1 = This is the full value
|
||||||
|
value2 = "Take the value in quotation marks"
|
||||||
|
value3 = 'Or take in apostrophes'
|
||||||
|
value4 => You can also comment // Another separator and comment
|
||||||
|
value5 => 'So you can also comment' # Yeah!
|
||||||
|
value6 => 'And you can even do that!' ; He-he;)
|
||||||
|
value7 = 1234567890 # decimal value
|
||||||
|
value8 => 12345.67890 ; float value
|
||||||
|
value9 => You can use large margins
|
||||||
|
value10 = // But a line without a value will not be read
|
||||||
|
value11 = //path # not working
|
||||||
|
value12 = "//path" // nice way (or '//path')
|
||||||
|
```
|
||||||
|
|
||||||
|
Read `settings.conf` file:
|
||||||
|
|
||||||
|
```d
|
||||||
|
import readconf;
|
||||||
|
import std.stdio;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
Config.file.read("./settings.conf");
|
||||||
|
|
||||||
|
foreach (key, param; Config.file.keys())
|
||||||
|
writefln("%s => %s", key, param);
|
||||||
|
|
||||||
|
int val7Int = Config.file.key("value7").toInt;
|
||||||
|
float val8Float = Config.file.key("value8").toFloat;
|
||||||
|
// Return default value as 0
|
||||||
|
int val8Int = Config.file.key("value8").toInt;
|
||||||
|
float val5Float = Config.file.key("value9").toFloat;
|
||||||
|
|
||||||
|
writefln(
|
||||||
|
"val7Int = %s; val8Float = %s; val8Int = %s; val5Float = %s;",
|
||||||
|
val7Int, val8Float, val8Int, val5Float
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Result:
|
||||||
|
|
||||||
|
![matches.png](img/matches.png)
|
||||||
|
|
||||||
|
```
|
||||||
|
value1 => This is the full value
|
||||||
|
value2 => Take the value in quotation marks
|
||||||
|
value3 => Or take in apostrophes
|
||||||
|
value4 => You can also comment
|
||||||
|
value5 => So you can also comment
|
||||||
|
value6 => And you can even do that!
|
||||||
|
value7 => 1234567890
|
||||||
|
value8 => 12345.67890
|
||||||
|
value9 => You can use large margins
|
||||||
|
value12 => //path
|
||||||
|
val7Int = 1234567890; val8Float = 12345.7; val8Int = 0; val5Float = 0;
|
||||||
|
```
|
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
"name": "readconf",
|
||||||
|
"authors": [
|
||||||
|
"Alexander Zhirov <alexander@zhirov.kz>"
|
||||||
|
],
|
||||||
|
"homepage": "https://git.zhirov.kz/dlang/readconf.git",
|
||||||
|
"license": "GPL-2.0",
|
||||||
|
"copyright": "© Alexander Zhirov, 2023",
|
||||||
|
"description": "Singleton for simple reading of the configuration file",
|
||||||
|
"targetType": "library",
|
||||||
|
"targetPath": "lib",
|
||||||
|
"targetName": "readconf",
|
||||||
|
"dependencies": {
|
||||||
|
"singlog": "~>0.1.0"
|
||||||
|
},
|
||||||
|
"version": "0.0.1"
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"fileVersion": 1,
|
||||||
|
"versions": {
|
||||||
|
"datefmt": "1.0.4",
|
||||||
|
"singlog": "0.1.0"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"defaultArchitecture": "x86_64",
|
||||||
|
"defaultCompiler": "ldc2"
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 69 KiB |
|
@ -0,0 +1,174 @@
|
||||||
|
module readconf;
|
||||||
|
|
||||||
|
import std.stdio, std.conv, std.path, std.file;
|
||||||
|
import core.stdc.stdlib : exit;
|
||||||
|
import std.regex;
|
||||||
|
import std.meta;
|
||||||
|
import singlog;
|
||||||
|
|
||||||
|
class Config
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
static Config config;
|
||||||
|
string path;
|
||||||
|
PP[string] properties;
|
||||||
|
bool readed = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parameter and its value with the ability to convert to the desired data type
|
||||||
|
*/
|
||||||
|
struct PP
|
||||||
|
{
|
||||||
|
private string property;
|
||||||
|
private string value;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checking for the presence of a parameter
|
||||||
|
* Returns: true if the parameter is missing, otherwise false
|
||||||
|
*/
|
||||||
|
@property bool empty()
|
||||||
|
{
|
||||||
|
return this.property.length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an integer value
|
||||||
|
* Returns: integer value or 0 if missing
|
||||||
|
*/
|
||||||
|
@property int toInt() const
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return to!int(this.value);
|
||||||
|
} catch (Exception) {
|
||||||
|
Log.msg.warning("Failed to convert parameter to integer type: " ~ this.property);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a floating point value
|
||||||
|
* Returns: floating point value or 0.0 if missing
|
||||||
|
*/
|
||||||
|
@property float toFloat() const
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return to!float(this.value);
|
||||||
|
} catch (Exception) {
|
||||||
|
Log.msg.warning("Failed to convert parameter to float type: " ~ this.property);
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a string representation of the value
|
||||||
|
* Returns: default string value
|
||||||
|
*/
|
||||||
|
@property string toString() const
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
alias toString this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reading the configuration file
|
||||||
|
*/
|
||||||
|
void readConfig()
|
||||||
|
{
|
||||||
|
File configuration;
|
||||||
|
|
||||||
|
try {
|
||||||
|
configuration = File(this.path, "r");
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.msg.error("Unable to open the configuration file " ~ this.path);
|
||||||
|
Log.msg.warning(e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string pattern = "^ *(\\w+)(( +=> +)|( += +))(?!\\/\\/)(([^ >\"'\\n#;].*?)|
|
||||||
|
(\"(.+?)\")|('(.+?)')){1} *( #.*?)?( ;.*?)?( \\/\\/.*)?$";
|
||||||
|
auto regular = regex(pattern, "m");
|
||||||
|
|
||||||
|
while (!configuration.eof())
|
||||||
|
{
|
||||||
|
string line = configuration.readln();
|
||||||
|
auto match = matchFirst(line, regular);
|
||||||
|
if (match)
|
||||||
|
{
|
||||||
|
int group = 5;
|
||||||
|
if (match[group].length)
|
||||||
|
{
|
||||||
|
if (match[group][0] == '\'')
|
||||||
|
group = 10;
|
||||||
|
if (match[group][0] == '\"')
|
||||||
|
group = 8;
|
||||||
|
}
|
||||||
|
this.properties[match[1]] = PP(match[1], match[group]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
configuration.close();
|
||||||
|
this.readed = true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.msg.error("Unable to close the configuration file " ~ this.path);
|
||||||
|
Log.msg.warning(e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this() {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Accessing the Config object
|
||||||
|
* Returns: Config Object
|
||||||
|
*/
|
||||||
|
@property static Config file()
|
||||||
|
{
|
||||||
|
if (this.config is null)
|
||||||
|
this.config = new Config;
|
||||||
|
|
||||||
|
return this.config;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the configuration file
|
||||||
|
* Params:
|
||||||
|
* path = the path to the configuration file
|
||||||
|
*/
|
||||||
|
void read(string path)
|
||||||
|
{
|
||||||
|
this.path = path;
|
||||||
|
if (!path.exists)
|
||||||
|
{
|
||||||
|
Log.msg.error("The configuration file does not exist: " ~ path);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
readConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the parameter value
|
||||||
|
* Params:
|
||||||
|
* key = parameter from the configuration file
|
||||||
|
* Returns: the value of the parameter in the PP structure view
|
||||||
|
*/
|
||||||
|
PP key(string key)
|
||||||
|
{
|
||||||
|
if (this.readed)
|
||||||
|
return key in this.properties ? this.properties[key] : PP();
|
||||||
|
Log.msg.warning("The configuration file was not read!");
|
||||||
|
return PP();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all keys and their values
|
||||||
|
* Returns: collection of properties structures PP
|
||||||
|
*/
|
||||||
|
PP[string] keys()
|
||||||
|
{
|
||||||
|
return this.properties;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue