diff --git a/CHANGELOG.md b/CHANGELOG.md index 3406c52f2..942af7ac4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## Next Release + +- Fixed `LogicValue.ofRadixString` round trips with empty separators and separators containing regular-expression metacharacters (). + ## 0.6.11 - Added `NetlistSynthesizer` for generating JSON netlists, with configurable synthesis passes, validation, and hierarchy support (). diff --git a/lib/src/values/logic_value.dart b/lib/src/values/logic_value.dart index b954d1c39..0b517a193 100644 --- a/lib/src/values/logic_value.dart +++ b/lib/src/values/logic_value.dart @@ -763,7 +763,10 @@ abstract class LogicValue implements Comparable { /// illegal characters /// in the string or too long of a value string. /// - /// Strings created by [toRadixString] are parsed by [ofRadixString]. + /// Strings created by [toRadixString] are parsed by [ofRadixString]. + /// [sepChar] is interpreted literally and must match the separator used when + /// formatting the string. An empty [sepChar] is allowed for strings without + /// separators. /// /// If the LogicValue width is not encoded as round number of radix /// characters, the leading character must be small enough to be encoded @@ -773,12 +776,13 @@ abstract class LogicValue implements Comparable { /// - 11'h4aa /// - 12'haa static LogicValue ofRadixString(String valueString, {String sepChar = '_'}) { - if (radixStringChars.contains(sepChar)) { + if (sepChar.isNotEmpty && radixStringChars.contains(sepChar)) { throw LogicValueConstructionException('separation character invalid'); } + final escapedSeparator = RegExp.escape(sepChar); if (RegExp(r'^\d+').firstMatch(valueString) != null) { final formatStr = - RegExp("^(\\d+)'([bqodh])([0-9aAbBcCdDeEfFzZxX<>$sepChar]*)") + RegExp("^(\\d+)'([bqodh])([0-9aAbBcCdDeEfFzZxX<>$escapedSeparator]*)") .firstMatch(valueString); if (formatStr != null) { if (valueString.length != formatStr.group(0)!.length) { diff --git a/test/logic_value_test.dart b/test/logic_value_test.dart index 0622439b4..203b36885 100644 --- a/test/logic_value_test.dart +++ b/test/logic_value_test.dart @@ -2144,6 +2144,21 @@ void main() { } }); + for (final separator in ['', ']', r'\', '[', '^', '.', '-']) { + test('radixString literal separator "$separator" round trip', () { + final known = LogicValue.ofInt(0x1234abcd, 40); + final fourState = LogicValue.ofString('10xz1010zz01'); + for (final radix in [2, 4, 8, 10, 16]) { + for (final value in [known, if (radix != 10) fourState]) { + final encoded = value.toRadixString( + radix: radix, leadingZeros: true, sepChar: separator); + expect( + LogicValue.ofRadixString(encoded, sepChar: separator), value); + } + } + }); + } + test('radixString space separators', () { final lv = LogicValue.ofRadixString("10'b10 0010 0111", sepChar: ' '); expect(lv.toInt(), equals(551));