Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ligen-csharp #79

Closed
wants to merge 50 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
a941773
Removing ligen-c C prefix on object names
notdanilo Aug 23, 2021
23eed01
Organizing C# generator
notdanilo Aug 24, 2021
6ab9d76
Naming convention
notdanilo Aug 24, 2021
19fbcf1
Naming convention and ligen-csharp
notdanilo Aug 24, 2021
5147d35
One less identation
notdanilo Aug 24, 2021
f4c7c4c
Using ligen-c in the example
notdanilo Aug 27, 2021
9a9ab9f
Module recursion
notdanilo Aug 27, 2021
bcbc441
Including 'literal' modules
notdanilo Aug 27, 2021
8434b1a
Iterating over all sub modules
notdanilo Aug 30, 2021
02ad1d2
Draft support for ignoring modules
notdanilo Aug 30, 2021
8b4175b
Using ligen without cargo-ligen
notdanilo Aug 31, 2021
9c82bf2
Modules with ignore won't be parsed, avoiding unimplemented features …
notdanilo Aug 31, 2021
1631e12
Adding enumeration
notdanilo Sep 1, 2021
955eaf7
Using paths to generate files
notdanilo Sep 6, 2021
fc592dd
Some notes
notdanilo Sep 6, 2021
c221ea5
Adding note to temp ffi project
notdanilo Sep 7, 2021
04529c8
ligen proc-macro added as attributes
notdanilo Sep 7, 2021
80f7088
Removed 'should_ignore' function
notdanilo Sep 8, 2021
40e638a
Removed 'ignored' field from Attributes
notdanilo Sep 8, 2021
a55fcd5
Renaming ligen proc_macro to inner_ligen
notdanilo Sep 8, 2021
01270af
Adding Import definition
notdanilo Sep 9, 2021
6a62d44
WIP custom marshaller
notdanilo Sep 9, 2021
f84dc7d
Adding FFI generation tests
notdanilo Sep 13, 2021
67c8fc4
Better test coverage and reworked example
notdanilo Sep 14, 2021
388b74d
Finding absolute paths of type usages
notdanilo Sep 16, 2021
c888fc0
Transforming wildcard imports into regular imports
notdanilo Sep 19, 2021
c4c80df
WIP - Marshaller
notdanilo Oct 3, 2021
f2b2ba4
WIP
notdanilo Oct 7, 2021
1393cab
Removed hardcoded values
notdanilo Oct 13, 2021
20961b6
ligen-csharp using templates
notdanilo Oct 14, 2021
0b1c3a3
Adding generics
notdanilo Oct 15, 2021
d7eed02
Generics in structures
notdanilo Oct 21, 2021
b511f6e
WIP ligen-csharp
notdanilo Dec 2, 2021
8402f0c
Adding tests
notdanilo Dec 3, 2021
7349964
Fixing opaque types references in ligen-csharp
notdanilo Dec 5, 2021
12809c9
Working opaque types
notdanilo Dec 12, 2021
4d9b6f4
Reading opaque types
notdanilo Dec 13, 2021
47f55ad
Reworking
notdanilo Dec 14, 2021
93342e0
WIP: Trying to use templates dir
notdanilo Dec 14, 2021
b9b9acb
A little something
notdanilo Dec 15, 2021
c26f5b8
WIP Rust exporter
notdanilo Dec 16, 2021
5e4e292
WIP Reworking module conversion
notdanilo Dec 16, 2021
7760de7
WIP File Module Loading
notdanilo Dec 17, 2021
f599d83
Cleaning up unused code
nyanilo Oct 1, 2022
734274a
Passing cargo check
nyanilo Oct 2, 2022
d2a5e0b
Fixing ligen-ir tests
nyanilo Oct 2, 2022
0dfde07
Fixed project and modules tests
nyanilo Oct 3, 2022
22c7a0c
Fixed marshaller tests
nyanilo Oct 3, 2022
bc7d670
Compileable ligen-c
nyanilo Oct 6, 2022
d2ad466
A few changes trying to fix the examples, but they need to be reworked
nyanilo Oct 6, 2022
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# IntelliJ idea auto-generated files
.idea
.gradle

# Rust files
/target
Expand Down
22 changes: 11 additions & 11 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
[workspace]
members = [
"ligen",
"ligen-c",
"ligen-cmake",
# "ligen-cpp/crates/core",
# "ligen-cpp/crates/macro",
# "ligen-cpp/crates/main",
# "ligen-cpp/examples/cpp-counter",
# "ligen-csharp/crates/core",
# "ligen-csharp/crates/macro",
# "ligen-csharp/crates/main",
# "ligen-csharp/examples/csharp-counter",
]
"ligen/ir",
"ligen/utils",
"ligen/traits",
"generators/ligen-cargo",
"generators/ligen-rust",
"generators/ligen-cmake",
"generators/ligen-c",
"generators/ligen-csharp",
"examples/example",
# "generators/ligen-csharp/tests/rust"
]
File renamed without changes.
File renamed without changes.
1 change: 1 addition & 0 deletions examples/example-c/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
build
13 changes: 13 additions & 0 deletions examples/example-c/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.0)
PROJECT("example-c")

IF(TARGET ${PROJECT_NAME})
RETURN()
ENDIF()

ADD_SUBDIRECTORY(../../target/ligen/example example)

AUX_SOURCE_DIRECTORY(src SOURCES)

ADD_EXECUTABLE(${PROJECT_NAME} ${SOURCES})
TARGET_LINK_LIBRARIES(${PROJECT_NAME} PUBLIC example)
14 changes: 14 additions & 0 deletions examples/example-c/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Counter-c

An example on how to use the c bindings generated by ligen-c.

### Requirements
1. `cmake`

### Building the project
1. `$ mkdir build`
2. `$ cd build`
3. `$ cmake ..`
4. `$ cmake --build .`

The compiled executable can be found inside the `build` folder.
44 changes: 44 additions & 0 deletions examples/example-c/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//#include <counter/person/sub_counter/Counter.h>
//#include <counter/ffi/rstring/RString.h>
//#include <counter/person/Person.h>
//
//#include <stdio.h>
//#include <string.h>
//
//#define string_assert_eq(a, b) { printf("assert(\"%s\" == \"%s\")\n", a, b); assert(!strcmp(a, b)); }
//
//int main(int argc, char **argv) {
// Counter counter = Counter_new(2);
// assert_eq(Counter_get_count(counter), 2);
// Counter_count(counter, 1);
// assert_eq(Counter_get_count(counter), 3);
// Counter_count(counter, 3);
// assert_eq(Counter_get_count(counter), 6);
// Counter_drop(counter);
//
// RString string = RString_new("Hello!");
// string_assert_eq("Hello!", RString_as_ptr(string));
// RString_drop(string);
//
// Person person = Person_new("Danilo", "Guanabara");
//
// RString fullName = Person_full_name(person);
// string_assert_eq("Danilo Guanabara", RString_as_ptr(fullName));
// RString_drop(fullName);
//
// Person_drop(person);
//
// return 0;
//}

#include <stdio.h>
#include <example.h>
#include <assert.h>

int main(int argc, char **argv) {
Instant* instant = now();
Duration* duration = elapsed(instant);
print_duration(duration);
assert(4 == add(1, 3));
return 0;
}
File renamed without changes.
22 changes: 22 additions & 0 deletions examples/example/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[package]
name = "example"
version = "0.1.0"
authors = ["Danilo Guanabara <danilo@sensorial.systems>"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[features]
bindings = ["ligen", "ligen-cargo", "ligen-rust", "ligen-csharp"]

[lib]
crate-type = ["lib", "staticlib"]

[dependencies]
ligen-macro = { path = "../../ligen/macro" }

[build-dependencies]
ligen = { path = "../../ligen", optional = true }
ligen-cargo = { path = "../../generators/ligen-cargo", optional = true }
ligen-rust = { path = "../../generators/ligen-rust", optional = true }
ligen-csharp = { path = "../../generators/ligen-csharp", optional = true }
7 changes: 7 additions & 0 deletions examples/example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Counter

An example on how to use ligen.

# Using

`cargo build --features=bindings`
24 changes: 24 additions & 0 deletions examples/example/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
fn main() {
#[cfg(feature = "bindings")]
{
use ligen::prelude::*;
use ligen::traits::build::{BuildSystem, BuildProfile};
use ligen_csharp::CSharpGenerator;
use ligen_cargo::{CargoProject, CargoGenerator, CargoBuilder};
use ligen_rust::RustGenerator;

match CargoProject::current().and_then(Project::try_from) {
Ok(project) => {
println!("Generating C# bindings...");
let rust_generator = RustGenerator::default();
let csharp_generator = CSharpGenerator::default();
let cargo_generator = CargoGenerator::default();
cargo_generator.generate(&project).expect("Failed to generate Cargo interface.");
rust_generator.generate(&project).expect("Failed to generate Rust interface.");
csharp_generator.generate(&project).expect("Failed to generate C# interface.");
CargoBuilder.build(&project, BuildProfile::Release).expect("Failed to build Cargo project.");
},
Err(_) => ()
}
}
}
13 changes: 13 additions & 0 deletions examples/example/src/ffi.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
use std::ffi::CStr;
use std::os::raw::c_char;

pub mod rstring;

#[repr(C)]
pub struct CChar(*const c_char);

impl From<CChar> for String {
fn from(cchar: CChar) -> Self {
unsafe { CStr::from_ptr(cchar.0).to_str().unwrap().to_string() }
}
}
44 changes: 44 additions & 0 deletions examples/example/src/ffi/rstring/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
use ligen_macro::ligen;

// inner_ligen!(MarshalTo(String, *mut RString));
// inner_ligen!(MarshalFrom(String, CChar));

use std::os::raw::c_char;

pub struct RString(std::ffi::CString);

impl RString {
pub fn new(string: *const c_char) -> Self {
string.into()
}

pub fn as_ptr(&self) -> *const c_char {
self.0.as_ptr()
}
}

impl From<String> for RString {
fn from(string: String) -> Self {
let string = std::ffi::CString::new(string).expect("Couldn't create CString.");
Self(string)
}
}

impl From<RString> for String {
fn from(string: RString) -> Self {
string.0.to_string_lossy().to_string()
}
}

impl From<*const c_char> for RString {
fn from(c_char: *const c_char) -> Self {
unsafe {
let string = std::ffi::CString::new(
std::ffi::CStr::from_ptr(c_char)
.to_string_lossy()
.to_string(),
).expect("Failed to create RString.");
Self(string)
}
}
}
7 changes: 7 additions & 0 deletions examples/example/src/ignored.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
ligen_macro::inner_ligen!(ignore);

pub struct Ignored;

impl Ignored {
pub fn ignored() -> Self { Self }
}
25 changes: 25 additions & 0 deletions examples/example/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

pub mod time;
pub use time::Instant;
pub use time::instant::Instant as RenamedInstant;
pub use time::duration::*;

pub fn add(a: u32, b: u32) -> u32 {
a + b
}

pub fn now() -> Instant {
Instant::now()
}

pub fn elapsed(instant: *mut Instant) -> *mut Duration {
unsafe {
Box::into_raw(Box::new((*instant).elapsed()))
}
}

pub fn print_duration(duration: *mut Duration) {
unsafe {
println!("{:#?}", (*duration).0);
}
}
16 changes: 16 additions & 0 deletions examples/example/src/person/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
pub mod sub_counter;

pub struct Person {
pub first_name: String,
pub last_name: String
}

impl Person {
pub fn new(first_name: String, last_name: String) -> Self {
Self { first_name, last_name }
}

pub fn full_name(&self) -> String {
format!("{} {}", self.first_name, self.last_name)
}
}
17 changes: 17 additions & 0 deletions examples/example/src/person/sub_counter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
pub struct Counter {
count: u32
}

impl Counter {
pub fn new(count: u32) -> Self {
Self { count }
}

pub fn count(&mut self, counts: u32) {
self.count += counts;
}

pub fn get_count(&self) -> u32 {
self.count
}
}
1 change: 1 addition & 0 deletions examples/example/src/time/duration.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub struct Duration(pub(crate) std::time::Duration);
16 changes: 16 additions & 0 deletions examples/example/src/time/instant.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use ligen_macro::ligen;

use crate::time::duration::Duration;

#[ligen(opaque)]
pub struct Instant(std::time::Instant);

impl Instant {
pub(crate) fn now() -> Self {
Self(std::time::Instant::now())
}

pub(crate) fn elapsed(&self) -> Duration {
Duration(self.0.elapsed())
}
}
5 changes: 5 additions & 0 deletions examples/example/src/time/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pub mod instant;
pub mod duration;

pub use instant::Instant;
pub use duration::Duration;
File renamed without changes.
2 changes: 1 addition & 1 deletion ligen-c/Cargo.toml → generators/ligen-c/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ readme = "../../README.md"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
ligen = { path = "../ligen" }
ligen = { path = "../../ligen" }
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
18 changes: 11 additions & 7 deletions ligen-c/src/ast/type_.rs → generators/ligen-c/src/ast/type_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,15 +105,15 @@ impl From<ir::Atomic> for Atomic {
ir::Integer::I32 => Atomic::Int,
ir::Integer::I64 => Atomic::LongLongInt,
ir::Integer::U128 | ir::Integer::USize | ir::Integer::I128 | ir::Integer::ISize => {
panic!("Atomic types u128, usize, i128 and isize not implemented")
todo!("Atomic types u128, usize, i128 and isize not implemented")
}
},
ir::Atomic::Float(float) => match float {
ir::Float::F32 => Atomic::Float,
ir::Float::F64 => Atomic::Double,
},
ir::Atomic::Boolean => panic!("Boolean not implemented"),
ir::Atomic::Character => panic!("16bit char not implemented"),
ir::Atomic::Boolean => todo!("Boolean not implemented"),
ir::Atomic::Character => todo!("16bit char not implemented"),
}
}
}
Expand All @@ -122,7 +122,7 @@ impl From<ir::Type> for Types {
fn from(type_: ir::Type) -> Self {
match type_ {
ir::Type::Atomic(atomic) => Self::Atomic(Atomic::from(atomic)),
ir::Type::Compound(compound) => {
ir::Type::Compound(compound, _generics) => {
Self::Compound(compound.segments.last().unwrap().clone())
}
ir::Type::Reference(_reference) => {
Expand All @@ -134,7 +134,10 @@ impl From<ir::Type> for Types {

impl From<ir::Reference> for Type {
fn from(type_: ir::Reference) -> Self {
let constness = if type_.is_constant { Some(Const) } else { None };
let constness = match type_.mutability {
ir::Mutability::Constant => Some(Const),
ir::Mutability::Mutable => None
};
let type_ = Types::from(*type_.type_.clone());
let pointer = Some(Pointer);
Self {
Expand All @@ -153,7 +156,7 @@ impl From<ir::Type> for Type {
type_: Types::Atomic(type_.into()),
pointer: None,
},
ir::Type::Compound(path) => Self {
ir::Type::Compound(path, _) => Self {
constness: None,
type_: Types::Compound(path.segments.last().unwrap().clone()),
pointer: None,
Expand All @@ -164,6 +167,7 @@ impl From<ir::Type> for Type {
}

use std::fmt;

impl fmt::Display for Type {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Some(_) = self.constness {
Expand All @@ -174,7 +178,7 @@ impl fmt::Display for Type {
Types::Atomic(atomic) => write!(f, "{}", atomic.as_ref())?,
Types::Compound(identifier) => match identifier.name.as_str() {
"String" => write!(f, "const char*")?,
_ => write!(f, "C{}", identifier.name)?,
_ => write!(f, "{}", identifier.name)?,
},
}

Expand Down
Loading