Skip to content
Snippets Groups Projects
Commit e5ba4a16 authored by Jiří Kalvoda's avatar Jiří Kalvoda
Browse files

ConfigParser: Error on unused sections and values

parent 4447138c
No related branches found
No related tags found
No related merge requests found
......@@ -146,6 +146,33 @@ class ConfigNoValueException: ConfigException
return $"{Value.Place}: Value needed." ;
}
}
class ConfigUnusedOptionException: ConfigException
{
public ConfigKeyValue Value;
public ConfigUnusedOptionException(ConfigKeyValue value)
{
Value = value;
}
public override string ErrorString()
{
return $"{Value.Place}: No such option." ;
}
}
class ConfigUnusedSectionException: ConfigException
{
public ConfigSection Section;
public ConfigUnusedSectionException(ConfigSection section)
{
Section = section;
}
public override string ErrorString()
{
if(Section.SectionName == null)
return $"Global section not allowed." ;
else
return $"{Section.SectionName}: No such section." ;
}
}
class ConfigParseValueException: ConfigException
{
public ConfigValue Value;
......@@ -279,6 +306,12 @@ class ConfigKeyValue: ConfigValue
internal string? amen;
internal string? tabs;
public string Key {get; init;}
public bool Used = false;
public ConfigKeyValue Use()
{
Used = true;
return this;
}
public override string FullName
{
get => Section.SectionName != null ? $"{Section.SectionName}: {Key}" : Key;
......@@ -338,6 +371,12 @@ class ConfigSection: IReadOnlyList<ConfigKeyValue>
public int Line;
List<ConfigKeyValue> values = new();
Dictionary<string, ConfigKeyValue> valueByName = new();
public bool Used = false;
public ConfigSection Use()
{
Used = true;
return this;
}
internal ConfigSection(ConfigParser _Root, string? _SectionName, int _line)
{
Root = _Root;
......@@ -371,7 +410,7 @@ class ConfigSection: IReadOnlyList<ConfigKeyValue>
{
if(!valueByName.TryGetValue(key, out var r))
return null;
return r;
return r.Use();
}
public ConfigValue OptionalDefaultIsSectionName(string key)
{
......@@ -381,7 +420,7 @@ class ConfigSection: IReadOnlyList<ConfigKeyValue>
{
if(!valueByName.TryGetValue(key, out var r))
throw new ConfigNotDefinedException(this, key);
return r;
return r.Use();
}
public bool Contains(string key)
{
......@@ -396,6 +435,14 @@ class ConfigSection: IReadOnlyList<ConfigKeyValue>
}
}
public ConfigSectionNameAsValue SectionNameAsValue() => new(this);
public void CheckUnused()
{
foreach(ConfigKeyValue it in this)
{
if(it.Used == false)
throw new ConfigUnusedOptionException(it);
}
}
}
class ConfigParser: IReadOnlyList<ConfigSection>
{
......@@ -516,13 +563,21 @@ class ConfigParser: IReadOnlyList<ConfigSection>
if(key == null) return MainSection;
if(!sectionByName.TryGetValue(key, out var r))
return null;
return r;
return r.Use();
}
public ConfigSection Mandatory(string? key)
{
if(key == null) return MainSection;
if(!sectionByName.TryGetValue(key, out var r))
throw new ConfigSectionNotDefinedException(key);
return r;
return r.Use();
}
public void CheckUnused()
{
foreach(ConfigSection it in this)
{
if(it.Used == false)
throw new ConfigUnusedSectionException(it);
}
}
}
......@@ -251,7 +251,10 @@ refresh
throw new Exception($"Missing constructor of {type} module");
Module module = (Module) constructor.Invoke(new object[]{});
modules.Add(addStandardModuleWrappers(s, module, this));
s.Use();
s.CheckUnused();
}
p.CheckUnused();
}
public List<Block> Get()
{
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment