Skip to content

Commit

Permalink
Simply formatting of constants and environment variables (implementat…
Browse files Browse the repository at this point in the history
…ion stays backwards compatible)
  • Loading branch information
JanWichelmann committed Apr 13, 2024
1 parent 76ac1d0 commit 02904d4
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 9 deletions.
38 changes: 31 additions & 7 deletions Microwalk/YamlConfigurationParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microwalk.FrameworkBase.Configuration;
using Microwalk.FrameworkBase.Exceptions;
using YamlDotNet.RepresentationModel;
Expand Down Expand Up @@ -99,10 +99,10 @@ private void ParseConfigurationFile(string path)
string constantValue = (constantNode.Value as YamlScalarNode)?.Value ?? throw new ConfigurationException("Could not parse constant value.");

// Apply existing constants to value
constantValue = Constants.Aggregate(constantValue, (current, replacement) => current.Replace(replacement.Key, replacement.Value));
constantValue = ReplaceConstants(constantValue);

// Store/update constant
Constants[$"$${constantName}$$"] = constantValue;
Constants[$"${constantName}"] = constantValue;
}

break;
Expand Down Expand Up @@ -150,9 +150,33 @@ private void ApplyConstants(Node currentNode)
}
else if(currentNode is ValueNode valueNode)
{
valueNode.Value = Constants.Aggregate(valueNode.Value, (current, replacement) => current?.Replace(replacement.Key, replacement.Value));
valueNode.Value = valueNode.Value != null ? ReplaceConstants(valueNode.Value) : "";
}
}

/// <summary>
/// Replaces constant expressions in the given string.
/// </summary>
/// <param name="value">String to replace constants in.</param>
/// <returns>Input string with replaced constants.</returns>
private string ReplaceConstants(string value)
{
// Find and handle constants
return Regex.Replace(value, @"(\$+[A-Za-z0-9_]+)\$*", match =>
{
// If this is a constant with the old format, remove one leading $ from its name
// $$NAME$$ -> $NAME (config variables)
// $$$NAME$$$ -> $$NAME (environment variables)
string constantName = match.Groups[1].Value;
if(match.Value.EndsWith('$'))
constantName = constantName.Substring(1);

if(Constants.TryGetValue(constantName, out string? constantValue))
return constantValue;

throw new ConfigurationException($"Can not resolve constant '{constantName}'.");
});
}

/// <summary>
/// Recursively merges the source node into the target node.
Expand Down Expand Up @@ -201,13 +225,13 @@ public void LoadConfigurationFile(string path)
RootNodes = new Dictionary<string, Node>();
Constants = new Dictionary<string, string>
{
{ "$$CONFIG_PATH$$", Path.GetDirectoryName(Path.GetFullPath(path)) ?? throw new Exception("Could not resolve configuration directory.") },
{ "$$CONFIG_FILENAME$$", Path.GetFileNameWithoutExtension(path) }
{ "$CONFIG_PATH", Path.GetDirectoryName(Path.GetFullPath(path)) ?? throw new Exception("Could not resolve configuration directory.") },
{ "$CONFIG_FILENAME", Path.GetFileNameWithoutExtension(path) }
};

// Load environment variables as constants as well
foreach(DictionaryEntry variable in Environment.GetEnvironmentVariables())
Constants.Add($"$$${(string)variable.Key}$$$", (string?)variable.Value ?? "");
Constants.Add($"$${(string)variable.Key}", (string?)variable.Value ?? "");

// Load passed configuration file
ParseConfigurationFile(path);
Expand Down
4 changes: 2 additions & 2 deletions docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ Base configuration file which should be loaded and parsed before the current one
Keys existing in both the base file and the current file are always superseded by those of the current file.

### `constants`
A number of arbitrary string constants, which can be referenced by `$$CONSTANT_NAME$$` in other parts of the file.
A number of arbitrary string constants, which can be referenced by `$CONSTANT_NAME` in other parts of the file.

Predefined constants:
- `CONFIG_PATH`<br>
Expand All @@ -77,7 +77,7 @@ Predefined constants:
Name of the main configuration file, without extension (e.g., `target-aes` for `target-aes.yml`).

### Enviroment variables
All environment variables of the current process environment are available as `$$$VARIABLE_NAME$$$` and are treated just like constants.
All environment variables of the current process environment are available as `$$VARIABLE_NAME` (mind the double `$`) and are treated just like constants.


## `general`
Expand Down

0 comments on commit 02904d4

Please sign in to comment.