1.1--- a/.hgignore Sun May 07 01:32:31 2023 -0400
1.2+++ b/.hgignore Sun May 07 18:06:13 2023 -0400
1.3@@ -1,4 +1,9 @@
1.4 out/.*
1.5 .*Cargo.lock$
1.6 .*target/.*
1.7-.*[.]fasl$
1.8\ No newline at end of file
1.9+ffi/_demo.c$
1.10+.*[.]fasl$
1.11+.*[.]o$
1.12+.*[.]so$
1.13+.*[.]dylib$
1.14+.*[.]a$
1.15\ No newline at end of file
2.1--- a/Cargo.toml Sun May 07 01:32:31 2023 -0400
2.2+++ b/Cargo.toml Sun May 07 18:06:13 2023 -0400
2.3@@ -1,7 +1,6 @@
2.4 [package]
2.5-name = "demo_ffi"
2.6+name = "demo"
2.7 version = "0.1.0"
2.8-edition = "2021"
2.9 build = "build.rs"
2.10 [lib]
2.11 path = "lib.rs"
2.12@@ -13,4 +12,4 @@
2.13 obj = {version = "0.1.0",path = "obj"}
2.14 fig = {version = "0.1.0",path = "fig"}
2.15 [build-dependencies]
2.16-cbindgen = "0.20"
2.17\ No newline at end of file
2.18+cbindgen = "0.24.3"
2.19\ No newline at end of file
4.1--- a/build.rs Sun May 07 01:32:31 2023 -0400
4.2+++ b/build.rs Sun May 07 18:06:13 2023 -0400
4.3@@ -6,13 +6,11 @@
4.4 .expect("CARGO_MANIFEST_DIR env var is not defined")
4.5 .into();
4.6 // let mpk_py = "build.py";
4.7- let config = cbindgen::Config::from_file("cbindgen.toml")
4.8- .expect("Unable to find cbindgen.toml configuration file");
4.9 let build_dir = crate_dir.join("ffi/");
4.10 if !build_dir.exists() {
4.11 create_dir(&build_dir).unwrap();
4.12 }
4.13- cbindgen::generate_with_config(&crate_dir, config)
4.14- .unwrap()
4.15- .write_to_file(build_dir.join("mpk_ffi.h"));
4.16+ cbindgen::generate(crate_dir)
4.17+ .expect("Unable to find cbindgen.toml configuration file")
4.18+ .write_to_file(build_dir.join("demo.h"));
4.19 }
5.1--- a/cbindgen.toml Sun May 07 01:32:31 2023 -0400
5.2+++ b/cbindgen.toml Sun May 07 18:06:13 2023 -0400
5.3@@ -1,11 +1,14 @@
5.4-include_guard = "mpk_ffi_h"
5.5+include_guard = "demo_h"
5.6 autogen_warning = "/* DO NOT TOUCH */"
5.7 include_version = true
5.8 language = "C"
5.9 cpp_compat = true
5.10 line_length = 88
5.11-
5.12+documentation = true
5.13 [parse]
5.14 parse_deps = true
5.15-include = ["mpk_config", "mpk_hash"]
5.16-extra_bindings = ["mpk_hash", "mpk_config"]
5.17+include = ["obj","fig","libc"]
5.18+extra_bindings = ["obj","fig","libc"]
5.19+#expand = ["demo","obj"]
5.20+#[parse.expand]
5.21+#crates = ["demo"]
5.22\ No newline at end of file
6.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2+++ b/ffi/build.py Sun May 07 18:06:13 2023 -0400
6.3@@ -0,0 +1,48 @@
6.4+try:
6.5+ from cffi import FFI
6.6+except ImportError:
6.7+ print("pip install cffi, included with PyPy")
6.8+
6.9+import os
6.10+import re
6.11+import pathlib
6.12+
6.13+
6.14+def parse_header(header):
6.15+ h = open(header, "r").read().lstrip()
6.16+ cdef = re.sub(
6.17+ r"^(#|\s*\/*\*|extern).*[\r\n]|.*\"C\"$|^(?:[\t ]*(?:\r?\n|\r))+",
6.18+ "",
6.19+ h,
6.20+ flags=re.MULTILINE,
6.21+ )
6.22+ return cdef
6.23+
6.24+
6.25+def init_ffi(cdef):
6.26+ ffi = FFI()
6.27+ ffi.set_source(
6.28+ "_demo",
6.29+ """
6.30+ #include "demo.h"
6.31+ """,
6.32+# libraries=["demo"],
6.33+ library_dirs=["."],
6.34+ include_dirs=["."],
6.35+ )
6.36+
6.37+ ffi.cdef(cdef)
6.38+
6.39+ return ffi
6.40+
6.41+
6.42+def compile(ffi, lib_dir, v):
6.43+ os.environ["LD_RUN_PATH"] = os.path.abspath(lib_dir)
6.44+ ffi.compile(verbose=v)
6.45+
6.46+
6.47+if __name__ == "__main__":
6.48+ build_dir = pathlib.Path(__file__).parent
6.49+ cdef = parse_header(build_dir / "demo.h")
6.50+ print(cdef)
6.51+ compile(init_ffi(cdef), build_dir, True)
7.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2+++ b/ffi/demo.h Sun May 07 18:06:13 2023 -0400
7.3@@ -0,0 +1,60 @@
7.4+#ifndef demo_h
7.5+#define demo_h
7.6+
7.7+/* Generated with cbindgen:0.24.3 */
7.8+
7.9+/* DO NOT TOUCH */
7.10+
7.11+#include <stdarg.h>
7.12+#include <stdbool.h>
7.13+#include <stdint.h>
7.14+#include <stdlib.h>
7.15+
7.16+typedef struct CustomService CustomService;
7.17+
7.18+/**
7.19+ * APPLICATION TYPES
7.20+ */
7.21+typedef struct Service Service;
7.22+
7.23+#ifdef __cplusplus
7.24+extern "C" {
7.25+#endif // __cplusplus
7.26+
7.27+void free_service(struct Service *ptr);
7.28+
7.29+struct Service *service_from_string(const char *ptr);
7.30+
7.31+struct Service *service_from_json_string(const char *ptr);
7.32+
7.33+char *service_to_json_string(const struct Service *ptr);
7.34+
7.35+struct Service *service_from_ron_string(const char *ptr);
7.36+
7.37+char *service_to_ron_string(const struct Service *ptr);
7.38+
7.39+struct Service *service_decode(const uint8_t *ptr, size_t len);
7.40+
7.41+uint8_t *service_encode(const struct Service *ptr);
7.42+
7.43+void free_custom_service(struct CustomService *ptr);
7.44+
7.45+struct CustomService *custom_service_from_string(const char *ptr);
7.46+
7.47+struct CustomService *custom_service_from_json_string(const char *ptr);
7.48+
7.49+char *custom_service_to_json_string(const struct CustomService *ptr);
7.50+
7.51+struct CustomService *custom_service_from_ron_string(const char *ptr);
7.52+
7.53+char *custom_service_to_ron_string(const struct CustomService *ptr);
7.54+
7.55+struct CustomService *custom_service_decode(const uint8_t *ptr, size_t len);
7.56+
7.57+uint8_t *custom_service_encode(const struct CustomService *ptr);
7.58+
7.59+#ifdef __cplusplus
7.60+} // extern "C"
7.61+#endif // __cplusplus
7.62+
7.63+#endif /* demo_h */
8.1--- a/ffi/mpk_ffi.h Sun May 07 01:32:31 2023 -0400
8.2+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
8.3@@ -1,13 +0,0 @@
8.4-#ifndef mpk_ffi_h
8.5-#define mpk_ffi_h
8.6-
8.7-/* Generated with cbindgen:0.20.0 */
8.8-
8.9-/* DO NOT TOUCH */
8.10-
8.11-#include <stdarg.h>
8.12-#include <stdbool.h>
8.13-#include <stdint.h>
8.14-#include <stdlib.h>
8.15-
8.16-#endif /* mpk_ffi_h */
9.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2+++ b/gen.rs Sun May 07 18:06:13 2023 -0400
9.3@@ -0,0 +1,84 @@
9.4+//! demo
9.5+pub use fig::*;
9.6+pub use obj::*;
9.7+use std::ffi::{CStr, CString}; //OsStr,Path
9.8+ //use std::os::unix::ffi::OsStrExt;
9.9+use std::slice;
9.10+use libc::{c_char,size_t};
9.11+
9.12+#[macro_export]
9.13+macro_rules! cdefn {
9.14+ (free $t:tt $n:tt) => {
9.15+ #[no_mangle]
9.16+ pub unsafe extern "C" fn $n(ptr: *mut $t) {
9.17+ if ptr.is_null() {
9.18+ return;
9.19+ }
9.20+ let _ = Box::from_raw(ptr);
9.21+ }
9.22+ };
9.23+ (from_string $t:tt $n:tt) => {
9.24+ #[no_mangle]
9.25+ pub unsafe extern "C" fn $n(ptr: *const c_char) -> *mut $t {
9.26+ assert!(!ptr.is_null());
9.27+ let p = CStr::from_ptr(ptr).to_str().unwrap();
9.28+ Box::into_raw(Box::new(p.into()))
9.29+ }
9.30+ };
9.31+ (json_string $t:tt $r:tt $w:tt) => {
9.32+ #[no_mangle]
9.33+ pub unsafe extern "C" fn $r(ptr: *const c_char) -> *mut $t {
9.34+ assert!(!ptr.is_null());
9.35+ let s = CStr::from_ptr(ptr);
9.36+ Box::into_raw(Box::new($t::from_json_str(&s.to_str().unwrap()).unwrap()))
9.37+ }
9.38+
9.39+ #[no_mangle]
9.40+ pub unsafe extern "C" fn $w(ptr: *const $t) -> *mut c_char {
9.41+ let p = &*ptr;
9.42+ let x = p.to_json_string().unwrap();
9.43+ CString::new(x.as_str().as_bytes()).unwrap().into_raw()
9.44+ }
9.45+ };
9.46+ (ron_string $t:tt $r:tt $w:tt) => {
9.47+ #[no_mangle]
9.48+ pub unsafe extern "C" fn $r(ptr: *const c_char) -> *mut $t {
9.49+ assert!(!ptr.is_null());
9.50+ let s = CStr::from_ptr(ptr);
9.51+ Box::into_raw(Box::new($t::from_ron_str(&s.to_str().unwrap()).unwrap()))
9.52+ }
9.53+
9.54+ #[no_mangle]
9.55+ pub unsafe extern "C" fn $w(ptr: *const $t) -> *mut c_char {
9.56+ let p = &*ptr;
9.57+ let x = p.to_ron_string().unwrap();
9.58+ CString::new(x.as_str().as_bytes()).unwrap().into_raw()
9.59+ }
9.60+ };
9.61+ (bytes $t:tt $r:tt $w:tt) => {
9.62+ #[no_mangle]
9.63+ pub unsafe extern "C" fn $r(ptr: *const u8, len: size_t) -> *mut $t {
9.64+ Box::into_raw(Box::new($t::decode(slice::from_raw_parts(ptr,len)).unwrap()))
9.65+ }
9.66+
9.67+ #[no_mangle]
9.68+ pub unsafe extern "C" fn $w(ptr: *const $t) -> *mut u8 {
9.69+ let p = &*ptr;
9.70+ let mut x = p.encode().unwrap();
9.71+ let r = x.as_mut_ptr();
9.72+ std::mem::forget(x);
9.73+ r
9.74+ }
9.75+ }
9.76+}
9.77+
9.78+cdefn!(free Service free_service);
9.79+cdefn!(from_string Service service_from_string);
9.80+cdefn!(json_string Service service_from_json_string service_to_json_string);
9.81+cdefn!(ron_string Service service_from_ron_string service_to_ron_string);
9.82+cdefn!(bytes Service service_decode service_encode);
9.83+cdefn!(free CustomService free_custom_service);
9.84+cdefn!(from_string CustomService custom_service_from_string);
9.85+cdefn!(json_string CustomService custom_service_from_json_string custom_service_to_json_string);
9.86+cdefn!(ron_string CustomService custom_service_from_ron_string custom_service_to_ron_string);
9.87+cdefn!(bytes CustomService custom_service_decode custom_service_encode);
10.1--- a/lib.rs Sun May 07 01:32:31 2023 -0400
10.2+++ b/lib.rs Sun May 07 18:06:13 2023 -0400
10.3@@ -1,3 +1,118 @@
10.4-//! demo_ffi
10.5-pub use obj::Service;
10.6-pub use fig;
10.7+//! demo/lib.rs --- generated by DEMO:RS-MACROEXPAND
10.8+extern crate obj;
10.9+extern crate libc;
10.10+//pub use fig::*;
10.11+use obj::{Objective,Service,CustomService};
10.12+use std::ffi::{CStr, CString};
10.13+use std::slice;
10.14+use libc::{c_char, size_t};
10.15+#[no_mangle]
10.16+pub unsafe extern "C" fn free_service(ptr: *mut Service) {
10.17+ if ptr.is_null() {
10.18+ return;
10.19+ }
10.20+ let _ = Box::from_raw(ptr);
10.21+}
10.22+#[no_mangle]
10.23+pub unsafe extern "C" fn service_from_string(ptr: *const c_char) -> *mut Service {
10.24+ assert!(!ptr.is_null());
10.25+ let p = CStr::from_ptr(ptr).to_str().unwrap();
10.26+ Box::into_raw(Box::new(p.into()))
10.27+}
10.28+#[no_mangle]
10.29+pub unsafe extern "C" fn service_from_json_string(ptr: *const c_char) -> *mut Service {
10.30+ assert!(!ptr.is_null());
10.31+ let s = CStr::from_ptr(ptr);
10.32+ Box::into_raw(Box::new(Service::from_json_str(&s.to_str().unwrap()).unwrap()))
10.33+}
10.34+#[no_mangle]
10.35+pub unsafe extern "C" fn service_to_json_string(ptr: *const Service) -> *mut c_char {
10.36+ let p = &*ptr;
10.37+ let x = p.to_json_string().unwrap();
10.38+ CString::new(x.as_str().as_bytes()).unwrap().into_raw()
10.39+}
10.40+#[no_mangle]
10.41+pub unsafe extern "C" fn service_from_ron_string(ptr: *const c_char) -> *mut Service {
10.42+ assert!(!ptr.is_null());
10.43+ let s = CStr::from_ptr(ptr);
10.44+ Box::into_raw(Box::new(Service::from_ron_str(&s.to_str().unwrap()).unwrap()))
10.45+}
10.46+#[no_mangle]
10.47+pub unsafe extern "C" fn service_to_ron_string(ptr: *const Service) -> *mut c_char {
10.48+ let p = &*ptr;
10.49+ let x = p.to_ron_string().unwrap();
10.50+ CString::new(x.as_str().as_bytes()).unwrap().into_raw()
10.51+}
10.52+#[no_mangle]
10.53+pub unsafe extern "C" fn service_decode(ptr: *const u8, len: size_t) -> *mut Service {
10.54+ Box::into_raw(Box::new(Service::decode(slice::from_raw_parts(ptr, len)).unwrap()))
10.55+}
10.56+#[no_mangle]
10.57+pub unsafe extern "C" fn service_encode(ptr: *const Service) -> *mut u8 {
10.58+ let p = &*ptr;
10.59+ let mut x = p.encode().unwrap();
10.60+ let r = x.as_mut_ptr();
10.61+ std::mem::forget(x);
10.62+ r
10.63+}
10.64+#[no_mangle]
10.65+pub unsafe extern "C" fn free_custom_service(ptr: *mut CustomService) {
10.66+ if ptr.is_null() {
10.67+ return;
10.68+ }
10.69+ let _ = Box::from_raw(ptr);
10.70+}
10.71+#[no_mangle]
10.72+pub unsafe extern "C" fn custom_service_from_string(
10.73+ ptr: *const c_char,
10.74+) -> *mut CustomService {
10.75+ assert!(!ptr.is_null());
10.76+ let p = CStr::from_ptr(ptr).to_str().unwrap();
10.77+ Box::into_raw(Box::new(p.into()))
10.78+}
10.79+#[no_mangle]
10.80+pub unsafe extern "C" fn custom_service_from_json_string(ptr: *const c_char) -> *mut CustomService {
10.81+ assert!(!ptr.is_null());
10.82+ let s = CStr::from_ptr(ptr);
10.83+ Box::into_raw(Box::new(CustomService::from_json_str(&s.to_str().unwrap()).unwrap()))}
10.84+#[no_mangle]
10.85+pub unsafe extern "C" fn custom_service_to_json_string(
10.86+ ptr: *const CustomService,
10.87+) -> *mut c_char {
10.88+ let p = &*ptr;
10.89+ let x = p.to_json_string().unwrap();
10.90+ CString::new(x.as_str().as_bytes()).unwrap().into_raw()
10.91+}
10.92+#[no_mangle]
10.93+pub unsafe extern "C" fn custom_service_from_ron_string(
10.94+ ptr: *const c_char,
10.95+) -> *mut CustomService {
10.96+ assert!(!ptr.is_null());
10.97+ let s = CStr::from_ptr(ptr);
10.98+ Box::into_raw(Box::new(CustomService::from_ron_str(&s.to_str().unwrap()).unwrap()))
10.99+}
10.100+#[no_mangle]
10.101+pub unsafe extern "C" fn custom_service_to_ron_string(
10.102+ ptr: *const CustomService,
10.103+) -> *mut c_char {
10.104+ let p = &*ptr;
10.105+ let x = p.to_ron_string().unwrap();
10.106+ CString::new(x.as_str().as_bytes()).unwrap().into_raw()
10.107+}
10.108+#[no_mangle]
10.109+pub unsafe extern "C" fn custom_service_decode(
10.110+ ptr: *const u8,
10.111+ len: size_t,
10.112+) -> *mut CustomService {
10.113+ Box::into_raw(
10.114+ Box::new(CustomService::decode(slice::from_raw_parts(ptr, len)).unwrap()),
10.115+ )
10.116+}
10.117+#[no_mangle]
10.118+pub unsafe extern "C" fn custom_service_encode(ptr: *const CustomService) -> *mut u8 {
10.119+ let p = &*ptr;
10.120+ let mut x = p.encode().unwrap();
10.121+ let r = x.as_mut_ptr();
10.122+ std::mem::forget(x);
10.123+ r
10.124+}
11.1--- a/makefile Sun May 07 01:32:31 2023 -0400
11.2+++ b/makefile Sun May 07 18:06:13 2023 -0400
11.3@@ -3,9 +3,10 @@
11.4 .PHONY:build
11.5 $(O):;mkdir -p $@
11.6 clean:;rm -rf out *.fasl;cargo clean
11.7+fmt:;scripts/fmt.ros
11.8 build:;scripts/build.ros
11.9 docs:;scripts/docs.ros
11.10 test:;scripts/test.ros
11.11 pack:;scripts/pack.ros
11.12 check:;scripts/check.ros
11.13-ci:clean build docs test pack;
11.14+ci:clean fmt build docs test pack;
12.1--- a/obj/src/lib.rs Sun May 07 01:32:31 2023 -0400
12.2+++ b/obj/src/lib.rs Sun May 07 18:06:13 2023 -0400
12.3@@ -5,13 +5,13 @@
12.4 mod types;
12.5 pub use types::*;
12.6
12.7+pub use bincode;
12.8 pub use ron;
12.9-pub use bincode;
12.10-pub use serde_json;
12.11 use ron::extensions::Extensions;
12.12 use serde::{de::DeserializeOwned, Deserialize, Serialize};
12.13+pub use serde_json;
12.14+use std::collections::{BTreeMap, HashMap};
12.15 use std::io;
12.16-use std::collections::{HashMap, BTreeMap};
12.17
12.18 /// common trait for all config modules. This trait provides functions
12.19 /// for de/serializing to/from RON, updating fields, and formatting.
12.20@@ -39,7 +39,7 @@
12.21 Ok(bincode::serialize_into(writer, self)?)
12.22 }
12.23
12.24- fn decode<'a>(&self, bytes: &'a [u8]) -> Result<Self>
12.25+ fn decode<'a>(bytes: &'a [u8]) -> Result<Self>
12.26 where
12.27 Self: Deserialize<'a>,
12.28 {
12.29@@ -130,5 +130,5 @@
12.30 }
12.31
12.32 impl<T> Objective for Vec<T> {}
12.33-impl<K,V> Objective for HashMap<K,V> {}
12.34-impl<K,V> Objective for BTreeMap<K,V> {}
12.35+impl<K, V> Objective for HashMap<K, V> {}
12.36+impl<K, V> Objective for BTreeMap<K, V> {}
13.1--- a/obj/src/types.rs Sun May 07 01:32:31 2023 -0400
13.2+++ b/obj/src/types.rs Sun May 07 18:06:13 2023 -0400
13.3@@ -1,15 +1,55 @@
13.4 //! obj/src/types.rs --- OBJ type descriptions used by our demo
13.5-use crate::{Error, Result, Objective, Serialize, Deserialize};
13.6+use crate::{Deserialize, Objective, Result, Serialize};
13.7 /// APPLICATION TYPES
13.8 #[derive(Serialize, Deserialize)]
13.9 pub enum Service {
13.10- Nws,
13.11- Fin,
13.12- Pvp,
13.13+ Weather,
13.14+ Stocks,
13.15+ Dynamic(Vec<Service>),
13.16+ Custom(CustomService),
13.17+ Test,
13.18 }
13.19
13.20 impl Objective for Service {}
13.21
13.22+impl From<&str> for Service {
13.23+ fn from(value: &str) -> Self {
13.24+ match value {
13.25+ "weather" => Service::Weather,
13.26+ "stocks" => Service::Stocks,
13.27+ "test" => Service::Test,
13.28+ s => {
13.29+ if s.contains(",") {
13.30+ let x = s.split(",");
13.31+ Service::Dynamic(
13.32+ x.map(|y| Service::Custom(y.into()))
13.33+ .collect::<Vec<Service>>(),
13.34+ )
13.35+ } else {
13.36+ Service::Custom(s.into())
13.37+ }
13.38+ }
13.39+ }
13.40+ }
13.41+}
13.42+
13.43+#[derive(Serialize, Deserialize)]
13.44+pub struct CustomService {
13.45+ name: String,
13.46+}
13.47+impl Objective for CustomService {}
13.48+impl From<CustomService> for Service {
13.49+ fn from(value: CustomService) -> Self {
13.50+ Service::Custom(value)
13.51+ }
13.52+}
13.53+impl From<&str> for CustomService {
13.54+ fn from(value: &str) -> Self {
13.55+ let name = value.to_owned();
13.56+ CustomService { name }
13.57+ }
13.58+}
13.59+
13.60 #[derive(Serialize, Deserialize)]
13.61 pub struct Complex<X: Objective> {
13.62 data: X,
14.1--- a/proc_macros/Cargo.toml Sun May 07 01:32:31 2023 -0400
14.2+++ b/proc_macros/Cargo.toml Sun May 07 18:06:13 2023 -0400
14.3@@ -2,10 +2,8 @@
14.4 name = "proc_macros"
14.5 version = "0.1.0"
14.6 edition = "2021"
14.7-
14.8 [lib]
14.9 proc-macro = true
14.10-
14.11 [dependencies]
14.12 quote = "1.0"
14.13 proc-macro2 = "1.0"
15.1--- a/proc_macros/src/lib.rs Sun May 07 01:32:31 2023 -0400
15.2+++ b/proc_macros/src/lib.rs Sun May 07 18:06:13 2023 -0400
15.3@@ -0,0 +1,1 @@
15.4+
16.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000
16.2+++ b/scripts/fmt.ros Sun May 07 18:06:13 2023 -0400
16.3@@ -0,0 +1,18 @@
16.4+#!/bin/sh
16.5+#|-*- mode:lisp -*-|#
16.6+#|
16.7+exec ros -Q -- $0 "$@"
16.8+|#
16.9+(progn ;;init forms
16.10+ (ros:ensure-asdf)
16.11+ #+quicklisp(ql:quickload '() :silent t)
16.12+ )
16.13+
16.14+(defpackage :ros.script.build.3891893519
16.15+ (:use :cl))
16.16+(in-package :ros.script.build.3891893519)
16.17+
16.18+(defun main (&rest argv)
16.19+ (declare (ignorable argv))
16.20+ (uiop:run-program "cargo fmt"))
16.21+;;; vim: set ft=lisp lisp:
17.1--- a/tk.lisp Sun May 07 01:32:31 2023 -0400
17.2+++ b/tk.lisp Sun May 07 18:06:13 2023 -0400
17.3@@ -2,7 +2,7 @@
17.4
17.5 (defvar *cargo-target* #P"/Users/ellis/dev/otom8/demo/target/")
17.6
17.7-(defmacro find-rust-dll (name &optional debug)
17.8+(defmacro rs-find-dll (name &optional debug)
17.9 "Find the rust dll specified by NAME."
17.10 (cond
17.11 ((uiop:directory-exists-p (merge-pathnames *cargo-target* "release"))
17.12@@ -13,6 +13,13 @@
17.13 (uiop:run-program `("cargo" "build" ,(unless debug "--release")) :output t)
17.14 `,(find-rust-dll name debug)))))
17.15
17.16+(defmacro rs-macroexpand (env &body body)
17.17+ "Cbindgen is quite the menace and really doesn't like our macros used
17.18+to generate C FFI bindings. To compensate for this, we use a tool
17.19+called cargo-expand by the most excellent dtolnay which expands Rust
17.20+macros. The expansions are assembled into an equivalent Rust source
17.21+file which cbindgen won't get stuck in an infinite compile loop on.")
17.22+
17.23 (defun random-id ()
17.24 (format NIL "~8,'0x-~8,'0x" (random #xFFFFFFFF) (get-universal-time)))
17.25