Skip to content

Commit

Permalink
#57 Updated regex and extension method to avoid exception when value …
Browse files Browse the repository at this point in the history
…[in VAL_ / VAL_TABLE_ tag] contain spaces between quotes. Added new tests.
  • Loading branch information
Whitehouse112 committed Oct 27, 2023
1 parent 3e3b03a commit ee7dffe
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 9 deletions.
51 changes: 51 additions & 0 deletions DbcParserLib.Tests/ValueTableLineParserTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,57 @@ public void ValueTableWithMapDefinitionIsParsedAndLinkedToChannel()
Assert.IsTrue(ParseLine(@"VAL_ 470 channelName 3 ""AEB_LOCK_STATE_SNA"" 2 ""AEB_LOCK_STATE_UNUSED"" 1 ""AEB_LOCK_STATE_UNLOCKED"" 0 ""AEB_LOCK_STATE_LOCKED"" ;", valueTableLineParsers, dbcBuilderMock.Object, nextLineProviderMock.Object));
}

[TestCase("VAL_TABLE_ TableName 0 \"Running\" 1 \" Idle\" ;")]
[TestCase("VAL_TABLE_ TableName 0 \"Running\" 1 \" Idle \" ;")]
[TestCase("VAL_TABLE_ TableName 0 \"Running\" 1 \" \" ;")]
[TestCase("VAL_TABLE_ TableName 0 \"Running\" 1 \"\" ;")]
public void ValueTableDefinitionWithSpacesInValuesIsParsed(string line)
{
var dbcBuilderMock = m_repository.Create<IDbcBuilder>();
var finalDict = new Dictionary<int, string>();

dbcBuilderMock.Setup(
builder => builder.AddNamedValueTable(
"TableName",
It.IsAny<Dictionary<int, string>>(),
It.IsAny<string>()
)).Callback<string, IReadOnlyDictionary<int, string>, string>((_, dict, _) =>
{
finalDict = new Dictionary<int, string>(dict);
});
var valueTableLineParsers = CreateParser();
var nextLineProviderMock = m_repository.Create<INextLineProvider>();

Assert.IsTrue(ParseLine(line, valueTableLineParsers, dbcBuilderMock.Object, nextLineProviderMock.Object));
Assert.AreEqual(2, finalDict.Count);
}

[TestCase("VAL_ 869 qGearboxOil 0 \"Running\" 1 \" Idle\" ;")]
[TestCase("VAL_ 869 qGearboxOil 0 \"Running\" 1 \" Idle \" ;")]
[TestCase("VAL_ 869 qGearboxOil 0 \"Running\" 1 \" \" ;")]
[TestCase("VAL_ 869 qGearboxOil 0 \"Running\" 1 \"\" ;")]
public void ValueTableWithSpacesInValuesIsParsed(string line)
{
var dbcBuilderMock = m_repository.Create<IDbcBuilder>();
var finalDict = new Dictionary<int, string>();

dbcBuilderMock.Setup(
builder => builder.LinkTableValuesToSignal(
869,
"qGearboxOil",
It.IsAny<Dictionary<int, string>>(),
It.IsAny<string>()
)).Callback<uint, string, IReadOnlyDictionary<int, string>, string>((_, _, dict, _) =>
{
finalDict = new Dictionary<int, string>(dict);
});
var valueTableLineParsers = CreateParser();
var nextLineProviderMock = m_repository.Create<INextLineProvider>();

Assert.IsTrue(ParseLine(line, valueTableLineParsers, dbcBuilderMock.Object, nextLineProviderMock.Object));
Assert.AreEqual(2, finalDict.Count);
}

[TestCase("VAL_ 869 qGearboxOil 0 \"Running\" 1 \"Idle\" ")]
[TestCase("VAL_ 869 qGearboxOil 0 \"Running\" 1 \"Idle\";")]
[TestCase("VAL_ -869 qGearboxOil 0 \"Running\" 1 \"Idle\" ;")]
Expand Down
8 changes: 5 additions & 3 deletions DbcParserLib/ExtensionsAndHelpers.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.IO;
using System.Linq;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using DbcParserLib.Model;

namespace DbcParserLib
Expand Down Expand Up @@ -71,6 +72,7 @@ internal static void AdjustExtendedId(this Message message)

internal static IReadOnlyDictionary<int, string> ToDictionary(this string records)
{
const string valueTableValueRegex = @"(-?\d+)\s+(""[^""]*"")";
var dict = new Dictionary<int, string>();

if (string.IsNullOrWhiteSpace(records))
Expand All @@ -85,9 +87,9 @@ internal static IReadOnlyDictionary<int, string> ToDictionary(this string record
if (string.IsNullOrWhiteSpace(line))
continue;

// Add duplicated key control and act (eg. strict -> break, warning -> keep going and log, silent-> keep going)
var tokens = line.Split(' ');
dict[int.Parse(tokens[0])] = tokens[1];
var match = Regex.Match(line, valueTableValueRegex);
if (match.Success)
dict[int.Parse(match.Groups[1].Value)] = match.Groups[2].Value;
}
}
return dict;
Expand Down
2 changes: 1 addition & 1 deletion DbcParserLib/Helpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public static string ConvertToMultiLine(string[] records, int offset)
var sb = new StringBuilder();
for (var i = offset; i < records.Length - 1; i += 2)
{
sb.AppendLine($"{records[i]} {records[i + 1]}");
sb.AppendFormat("{0} {1} {2}", records[i], records[i+1], '\n');
}

return sb.ToString();
Expand Down
7 changes: 4 additions & 3 deletions DbcParserLib/Parsers/ValueTableDefinitionLineParser.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Text.RegularExpressions;
using System.Text.RegularExpressions;
using DbcParserLib.Observers;

namespace DbcParserLib.Parsers
Expand All @@ -8,6 +7,8 @@ internal class ValueTableDefinitionLineParser : ILineParser
{
private const string ValueTableDefinitionLineStarter = "VAL_TABLE_ ";
private const string ValueTableDefinitionParsingRegex = @"VAL_TABLE_\s+([a-zA-Z_][\w]*)\s+((?:\d+\s+(?:""[^""]*"")\s+)*)\s*;";
private const string ValueTableNewLineRegex = @"(""[^""]*""\s+)";
private const string ValueTableNewLineRegexReplace = "$1\n";

private readonly IParseFailureObserver m_observer;

Expand All @@ -26,7 +27,7 @@ public bool TryParse(string line, IDbcBuilder builder, INextLineProvider nextLin
var match = Regex.Match(cleanLine, ValueTableDefinitionParsingRegex);
if (match.Success)
{
var valueTable = match.Groups[2].Value.Replace("\" ", "\"" + Environment.NewLine);
var valueTable = Regex.Replace(match.Groups[2].Value.TrimStart(), ValueTableNewLineRegex, ValueTableNewLineRegexReplace);
var valueTableDictionary = valueTable.ToDictionary();
builder.AddNamedValueTable(match.Groups[1].Value, valueTableDictionary, valueTable);
}
Expand Down
5 changes: 3 additions & 2 deletions DbcParserLib/Parsers/ValueTableLineParser.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System;
using System.Text.RegularExpressions;
using DbcParserLib.Observers;

Expand All @@ -9,6 +8,8 @@ internal class ValueTableLineParser : ILineParser
private const string ValueTableLineStarter = "VAL_ ";
private const string ValueTableLinkParsingRegex = @"VAL_\s+(\d+)\s+([a-zA-Z_][\w]*)\s+([a-zA-Z_][\w]*)\s*;";
private const string ValueTableParsingRegex = @"VAL_\s+(?:(?:(\d+)\s+([a-zA-Z_][\w]*))|([a-zA-Z_][\w]*))\s+((?:(?:-?\d+)\s+(?:""[^""]*"")\s+)*)\s*;";
private const string ValueTableNewLineRegex = @"(""[^""]*""\s+)";
private const string ValueTableNewLineRegexReplace = "$1\n";

private readonly IParseFailureObserver m_observer;

Expand All @@ -34,7 +35,7 @@ public bool TryParse(string line, IDbcBuilder builder, INextLineProvider nextLin
match = Regex.Match(cleanLine, ValueTableParsingRegex);
if (match.Success)
{
var valueTable = match.Groups[4].Value.TrimStart().Replace("\" ", "\"" + Environment.NewLine);
var valueTable = Regex.Replace(match.Groups[4].Value.TrimStart(), ValueTableNewLineRegex, ValueTableNewLineRegexReplace);
var valueTableDictionary = valueTable.ToDictionary();
if (match.Groups[3].Value != "")
builder.LinkTableValuesToEnvironmentVariable(match.Groups[3].Value, valueTableDictionary);
Expand Down

0 comments on commit ee7dffe

Please sign in to comment.