commit
671fcd3968
@ -0,0 +1,34 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cowslice"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"rustc_version",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc_version"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||||
|
dependencies = [
|
||||||
|
"semver",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "semver"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||||
|
dependencies = [
|
||||||
|
"semver-parser",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "semver-parser"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
@ -0,0 +1,11 @@
|
|||||||
|
[package]
|
||||||
|
name = "cowslice"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
rustc_version = "0.2"
|
@ -0,0 +1,27 @@
|
|||||||
|
|
||||||
|
extern crate rustc_version;
|
||||||
|
use rustc_version::{version, version_meta, Channel};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// Assert we haven't travelled back in time
|
||||||
|
assert!(version().unwrap().major >= 1);
|
||||||
|
|
||||||
|
// Set cfg flags depending on release channel
|
||||||
|
match version_meta().unwrap().channel {
|
||||||
|
Channel::Stable => {
|
||||||
|
println!("cargo:rustc-cfg=stable");
|
||||||
|
}
|
||||||
|
Channel::Beta => {
|
||||||
|
println!("cargo:rustc-cfg=beta");
|
||||||
|
}
|
||||||
|
Channel::Nightly => {
|
||||||
|
println!("cargo:rustc-cfg=nightly");
|
||||||
|
}
|
||||||
|
Channel::Dev => {
|
||||||
|
println!("cargo:rustc-cfg=dev");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Link to `libcow.a`
|
||||||
|
println!(r"cargo:rustc-link-search=./lib");
|
||||||
|
println!(r"cargo:rustc-link-lib=cow");
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
use super::*;
|
||||||
|
use std::{error, fmt};
|
||||||
|
use std::ffi::CStr;
|
||||||
|
|
||||||
|
/// A `libcow` error object.
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||||
|
#[repr(transparent)]
|
||||||
|
pub struct Error(i32);
|
||||||
|
|
||||||
|
impl Error
|
||||||
|
{
|
||||||
|
/// The last error in `libcow`.
|
||||||
|
#[inline(always)] pub fn last() -> Self
|
||||||
|
{
|
||||||
|
Self(unsafe {ffi::cow_err()})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl error::Error for Error{}
|
||||||
|
impl fmt::Display for Error
|
||||||
|
{
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
|
||||||
|
{
|
||||||
|
const DEFAULT: &'static [u8] = b"unknown\0"; // must be `nul`'d
|
||||||
|
let cstr = unsafe {
|
||||||
|
let ptr = ffi::cow_err_msg(self.0);
|
||||||
|
if ptr.is_null() {
|
||||||
|
CStr::from_bytes_with_nul_unchecked(DEFAULT)
|
||||||
|
} else {
|
||||||
|
let ptr = *ptr;
|
||||||
|
if ptr.is_null() {
|
||||||
|
CStr::from_bytes_with_nul_unchecked(DEFAULT)
|
||||||
|
} else {
|
||||||
|
CStr::from_ptr(ptr as *const i8)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
write!(f, "{}", cstr.to_string_lossy())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,29 @@
|
|||||||
|
//! Interfaces with the C library
|
||||||
|
use core::ffi::c_void;
|
||||||
|
|
||||||
|
/// Raw `cow_t*`
|
||||||
|
///
|
||||||
|
/// This is, essentially, a pointer to the origin (`void*`) pointer.
|
||||||
|
/// So is represented as `*mut RawHandle == void**`.
|
||||||
|
pub type RawHandle = *mut c_void;
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
pub fn cow_create(sz: usize) -> *mut RawHandle;
|
||||||
|
pub fn cow_free(cow: *mut RawHandle);
|
||||||
|
pub fn cow_clone(cow: *const RawHandle) -> *mut RawHandle;
|
||||||
|
|
||||||
|
pub fn cow_is_fake(cow: *const RawHandle) -> i32;
|
||||||
|
pub fn cow_size(cow: *const RawHandle) -> usize;
|
||||||
|
|
||||||
|
pub fn cow_err() -> i32;
|
||||||
|
pub fn cow_err_msg(kind: i32) -> *const *const u8;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)] pub unsafe fn cow_area_mut(cow: *mut RawHandle) -> *mut c_void
|
||||||
|
{
|
||||||
|
*cow
|
||||||
|
}
|
||||||
|
#[inline(always)] pub unsafe fn cow_area(cow: *const RawHandle) -> *const c_void
|
||||||
|
{
|
||||||
|
(*cow) as *const _
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
mod ffi;
|
||||||
|
|
||||||
|
pub mod error;
|
||||||
|
pub use error::Error;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
#[test]
|
||||||
|
fn link_works() {
|
||||||
|
unsafe {
|
||||||
|
let raw_h = super::ffi::cow_create(100);
|
||||||
|
assert_ne!(raw_h as usize, 0);
|
||||||
|
println!("Raw handle pointer is {:p}", raw_h);
|
||||||
|
super::ffi::cow_free(raw_h);
|
||||||
|
}
|
||||||
|
unsafe {
|
||||||
|
assert_eq!(super::ffi::cow_err(), 1, "There was an error in `cow_free`");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue