[ffigen] Handled proper conversion of macro doubles. (#113)
* Fixed issues with macros with value double.infinity and double.NaN
diff --git a/pkgs/ffigen/CHANGELOG.md b/pkgs/ffigen/CHANGELOG.md
index 7b452c5..b452cb9 100644
--- a/pkgs/ffigen/CHANGELOG.md
+++ b/pkgs/ffigen/CHANGELOG.md
@@ -1,3 +1,6 @@
+# 1.0.5
+- Fixed issues with generating macros of type `double.Infinity` and `double.NaN`.
+
# 1.0.4
- Updated code to use `dart format` instead of `dartfmt` for sdk version `>= 2.10.0`.
diff --git a/pkgs/ffigen/lib/src/header_parser/sub_parsers/macro_parser.dart b/pkgs/ffigen/lib/src/header_parser/sub_parsers/macro_parser.dart
index 16cf4a1..6c13ada 100644
--- a/pkgs/ffigen/lib/src/header_parser/sub_parsers/macro_parser.dart
+++ b/pkgs/ffigen/lib/src/header_parser/sub_parsers/macro_parser.dart
@@ -6,6 +6,7 @@
import 'dart:io';
import 'dart:typed_data';
+import 'package:ffigen/src/strings.dart' as strings;
import 'package:path/path.dart' as p;
import 'package:ffi/ffi.dart';
import 'package:ffigen/src/code_generator.dart';
@@ -128,7 +129,8 @@
originalName: savedMacros[macroName].originalName,
name: macroName,
rawType: 'double',
- rawValue: clang.clang_EvalResult_getAsDouble(e).toString(),
+ rawValue:
+ _writeDoubleAsString(clang.clang_EvalResult_getAsDouble(e)),
);
break;
case clang_types.CXEvalResultKind.CXEval_StrLiteral:
@@ -322,3 +324,18 @@
/// In all other cases, simply convert to string.
return String.fromCharCode(char);
}
+
+/// Converts a double to a string, handling cases like Infinity and NaN.
+String _writeDoubleAsString(double d) {
+ if (d.isFinite) {
+ return d.toString();
+ } else {
+ // The only Non-Finite numbers are Infinity, NegativeInfinity and NaN.
+ if (d.isInfinite) {
+ return d.isNegative
+ ? strings.doubleNegativeInfinity
+ : strings.doubleInfinity;
+ }
+ return strings.doubleNaN;
+ }
+}
diff --git a/pkgs/ffigen/lib/src/strings.dart b/pkgs/ffigen/lib/src/strings.dart
index 2cd2697..5a81450 100644
--- a/pkgs/ffigen/lib/src/strings.dart
+++ b/pkgs/ffigen/lib/src/strings.dart
@@ -108,3 +108,8 @@
const libclang_dylib_linux = 'libwrapped_clang.so';
const libclang_dylib_macos = 'libwrapped_clang.dylib';
const libclang_dylib_windows = 'wrapped_clang.dll';
+
+// Writen doubles
+const doubleInfinity = 'double.infinity';
+const doubleNegativeInfinity = 'double.negativeInfinity';
+const doubleNaN = 'double.nan';
diff --git a/pkgs/ffigen/pubspec.yaml b/pkgs/ffigen/pubspec.yaml
index a03c62e..7b1185b 100644
--- a/pkgs/ffigen/pubspec.yaml
+++ b/pkgs/ffigen/pubspec.yaml
@@ -3,7 +3,7 @@
# BSD-style license that can be found in the LICENSE file.
name: ffigen
-version: 1.0.4
+version: 1.0.5
homepage: https://github.com/dart-lang/ffigen
description: Experimental generator for FFI bindings, using LibClang to parse C header files.
diff --git a/pkgs/ffigen/test/header_parser_tests/macros.h b/pkgs/ffigen/test/header_parser_tests/macros.h
index e58d4ac..90bbd45 100644
--- a/pkgs/ffigen/test/header_parser_tests/macros.h
+++ b/pkgs/ffigen/test/header_parser_tests/macros.h
@@ -1,3 +1,5 @@
+#include<math.h>
+
#define TEST1 1.1
#define TEST2 10
#define TEST3 (TEST1 + TEST2)
@@ -23,3 +25,8 @@
#define TEST11 "\x80"
#define TEST12 "hello\n\t\r\v\b"
#define TEST13 "test\\"
+
+// Infinity, NaN and Negative Infinity.
+#define TEST14 INFINITY
+#define TEST15 -INFINITY
+#define TEST16 NAN
diff --git a/pkgs/ffigen/test/header_parser_tests/macros_test.dart b/pkgs/ffigen/test/header_parser_tests/macros_test.dart
index 9b279e7..6ad5090 100644
--- a/pkgs/ffigen/test/header_parser_tests/macros_test.dart
+++ b/pkgs/ffigen/test/header_parser_tests/macros_test.dart
@@ -27,6 +27,8 @@
${strings.headers}:
${strings.entryPoints}:
- 'test/header_parser_tests/macros.h'
+ ${strings.includeDirectives}:
+ - '**macros.h'
''') as yaml.YamlMap),
);
});
@@ -84,6 +86,18 @@
expect(actual.getBindingAsString('TEST13'),
expected.getBindingAsString('TEST13'));
});
+ test('TEST14', () {
+ expect(actual.getBindingAsString('TEST14'),
+ expected.getBindingAsString('TEST14'));
+ });
+ test('TEST15', () {
+ expect(actual.getBindingAsString('TEST15'),
+ expected.getBindingAsString('TEST15'));
+ });
+ test('TEST16', () {
+ expect(actual.getBindingAsString('TEST16'),
+ expected.getBindingAsString('TEST16'));
+ });
});
}
@@ -104,6 +118,13 @@
Constant(
name: 'TEST12', rawType: 'String', rawValue: r"'hello\n\t\r\v\b'"),
Constant(name: 'TEST13', rawType: 'String', rawValue: r"'test\\'"),
+ Constant(
+ name: 'TEST14', rawType: 'double', rawValue: strings.doubleInfinity),
+ Constant(
+ name: 'TEST15',
+ rawType: 'double',
+ rawValue: strings.doubleNegativeInfinity),
+ Constant(name: 'TEST16', rawType: 'double', rawValue: strings.doubleNaN),
],
);
}