Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions csbindgen-tests/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,15 @@ fn main() -> Result<(), Box<dyn Error>> {
.generate_csharp_file("../dotnet-sandbox/NestedModuleTests.cs")
.unwrap();

csbindgen::Builder::default()
.input_extern_file("src/negative_constants.rs")
.csharp_class_name("NegativeConstantsTests")
.csharp_dll_name("csbindgen_tests_negative_constants")
.csharp_use_function_pointer(true)
.csharp_generate_const_filter(|_| true)
.generate_csharp_file("../dotnet-sandbox/NegativeConstantsTests.cs")
.unwrap();

csbindgen::Builder::new()
.input_bindgen_file("src/zstd.rs")
.method_filter(|x| x.starts_with("ZSTD_"))
Expand Down
6 changes: 6 additions & 0 deletions csbindgen-tests/src/negative_constants.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
pub const CONST_U32: u32 = 1;
pub const CONST_U16: u16 = 42;
pub const CONST_U32_IN_BRACKETS: u32 = (420);
pub const CONST_I32: i32 = -1;
pub const CONST_I16: i16 = -42;
pub const CONST_I32_IN_BRACKETS: i32 = (-(420));
60 changes: 35 additions & 25 deletions csbindgen/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -382,32 +382,32 @@ pub fn collect_const(
if filter(const_name.as_str()) {
let t = parse_type(&ct.ty);

if let syn::Expr::Lit(lit_expr) = &*ct.expr {
let value = match &lit_expr.lit {
syn::Lit::Str(s) => {
format!("\"{}\"", s.value())
let expr = peel_expr(ct.expr.as_ref());
let value = match expr {
syn::Expr::Lit(lit_expr) => match &lit_expr.lit {
syn::Lit::Str(s) => Some(format!("\"{}\"", s.value())),
syn::Lit::ByteStr(bs) => Some(format!("{:?}", bs.value())),
syn::Lit::Byte(b) => Some(format!("{}", b.value())),
syn::Lit::Char(c) => Some(format!("'{}'", c.value())),
syn::Lit::Int(i) => Some(format!("{}", i.base10_parse::<i64>().unwrap())),
syn::Lit::Float(f) => Some(format!("{}", f.base10_parse::<f64>().unwrap())),
syn::Lit::Bool(b) => Some(format!("{}", b.value)),
_ => Some(String::new()),
},
syn::Expr::Unary(unary_expr) if matches!(unary_expr.op, syn::UnOp::Neg(_)) => {
let inner = peel_expr(unary_expr.expr.as_ref());
match inner {
syn::Expr::Lit(lit_expr) => match &lit_expr.lit {
syn::Lit::Int(i) => Some(format!("-{}", i.base10_digits())),
syn::Lit::Float(f) => Some(format!("-{}", f.base10_digits())),
_ => None,
},
_ => None,
}
syn::Lit::ByteStr(bs) => {
format!("{:?}", bs.value())
}
syn::Lit::Byte(b) => {
format!("{}", b.value())
}
syn::Lit::Char(c) => {
format!("'{}'", c.value())
}
syn::Lit::Int(i) => {
format!("{}", i.base10_parse::<i64>().unwrap())
}
syn::Lit::Float(f) => {
format!("{}", f.base10_parse::<f64>().unwrap())
}
syn::Lit::Bool(b) => {
format!("{}", b.value)
}
_ => String::new(),
};

}
_ => None,
};
if let Some(value) = value {
result.push(RustConst {
const_name,
rust_type: t,
Expand Down Expand Up @@ -728,6 +728,16 @@ fn parse_type(t: &syn::Type) -> RustType {
}
}

fn peel_expr(mut e: &syn::Expr) -> &syn::Expr {
loop {
match e {
syn::Expr::Group(g) => e = &g.expr,
syn::Expr::Paren(p) => e = &p.expr,
_ => return e,
}
}
}

fn parse_type_path(t: &syn::TypePath) -> RustType {
let last_segment = t.path.segments.last().unwrap();
if let syn::PathArguments::AngleBracketed(x) = &last_segment.arguments {
Expand Down
32 changes: 32 additions & 0 deletions dotnet-sandbox/NegativeConstantsTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// <auto-generated>
// This code is generated by csbindgen.
// DON'T CHANGE THIS DIRECTLY.
// </auto-generated>
#pragma warning disable CS8500
#pragma warning disable CS8981
using System;
using System.Runtime.InteropServices;


namespace CsBindgen
{
internal static unsafe partial class NegativeConstantsTests
{
const string __DllName = "csbindgen_tests_negative_constants";

internal const uint CONST_U32 = 1;
internal const ushort CONST_U16 = 42;
internal const uint CONST_U32_IN_BRACKETS = 420;
internal const int CONST_I32 = -1;
internal const short CONST_I16 = -42;
internal const int CONST_I32_IN_BRACKETS = -420;





}



}