fish-shell/fish-rust/src/ffi.rs

128 lines
3.3 KiB
Rust
Raw Normal View History

2023-01-15 06:56:24 +08:00
use crate::wchar::{self};
#[rustfmt::skip]
use ::std::pin::Pin;
#[rustfmt::skip]
2023-01-15 06:56:24 +08:00
use ::std::slice;
use autocxx::prelude::*;
use cxx::SharedPtr;
2023-01-15 06:56:24 +08:00
// autocxx has been hacked up to know about this.
pub type wchar_t = u32;
include_cpp! {
#include "fds.h"
#include "wutil.h"
#include "flog.h"
#include "io.h"
#include "parse_util.h"
#include "wildcard.h"
2023-02-05 16:35:06 +08:00
#include "tokenizer.h"
2023-01-15 06:56:24 +08:00
#include "parser.h"
#include "proc.h"
#include "common.h"
#include "builtin.h"
2023-02-05 16:35:06 +08:00
#include "fallback.h"
2023-01-15 06:56:24 +08:00
safety!(unsafe_ffi)
generate_pod!("wcharz_t")
generate!("make_fd_nonblocking")
generate!("wperror")
generate_pod!("pipes_ffi_t")
generate!("make_pipes_ffi")
2023-02-05 16:35:06 +08:00
generate!("valid_var_name_char")
2023-01-15 06:56:24 +08:00
generate!("get_flog_file_fd")
generate!("parse_util_unescape_wildcards")
2023-02-05 16:35:06 +08:00
generate!("fish_wcwidth")
generate!("fish_wcswidth")
2023-01-15 06:56:24 +08:00
generate!("wildcard_match")
generate!("wgettext_ptr")
2023-01-15 06:56:24 +08:00
generate!("parser_t")
generate!("job_t")
generate!("process_t")
generate!("proc_wait_any")
generate!("output_stream_t")
generate!("io_streams_t")
generate_pod!("RustFFIJobList")
generate_pod!("RustFFIProcList")
generate_pod!("RustBuiltin")
generate!("builtin_missing_argument")
generate!("builtin_unknown_option")
generate!("builtin_print_help")
generate!("wait_handle_t")
generate!("wait_handle_store_t")
}
impl parser_t {
pub fn get_jobs(&self) -> &[SharedPtr<job_t>] {
let ffi_jobs = self.ffi_jobs();
unsafe { slice::from_raw_parts(ffi_jobs.jobs, ffi_jobs.count) }
}
}
impl job_t {
#[allow(clippy::mut_from_ref)]
pub fn get_procs(&self) -> &mut [UniquePtr<process_t>] {
let ffi_procs = self.ffi_processes();
unsafe { slice::from_raw_parts_mut(ffi_procs.procs, ffi_procs.count) }
}
2023-01-15 06:56:24 +08:00
}
/// Allow wcharz_t to be "into" wstr.
impl From<wcharz_t> for &wchar::wstr {
fn from(w: wcharz_t) -> Self {
let len = w.length();
let v = unsafe { slice::from_raw_parts(w.str_ as *const u32, len) };
wchar::wstr::from_slice(v).expect("Invalid UTF-32")
}
}
/// Allow wcharz_t to be "into" WString.
impl From<wcharz_t> for wchar::WString {
fn from(w: wcharz_t) -> Self {
let len = w.length();
let v = unsafe { slice::from_raw_parts(w.str_ as *const u32, len).to_vec() };
Self::from_vec(v).expect("Invalid UTF-32")
}
}
/// A bogus trait for turning &mut Foo into Pin<&mut Foo>.
/// autocxx enforces that non-const methods must be called through Pin,
/// but this means we can't pass around mutable references to types like parser_t.
/// We also don't want to assert that parser_t is Unpin.
/// So we just allow constructing a pin from a mutable reference; none of the C++ code.
/// It's worth considering disabling this in cxx; for now we use this trait.
/// Eventually parser_t and io_streams_t will not require Pin so we just unsafe-it away.
pub trait Repin {
fn pin(&mut self) -> Pin<&mut Self> {
unsafe { Pin::new_unchecked(self) }
}
fn unpin(self: Pin<&mut Self>) -> &mut Self {
unsafe { self.get_unchecked_mut() }
}
}
// Implement Repin for our types.
impl Repin for parser_t {}
impl Repin for job_t {}
impl Repin for process_t {}
impl Repin for io_streams_t {}
impl Repin for output_stream_t {}
2023-01-15 06:56:24 +08:00
pub use autocxx::c_int;
pub use ffi::*;
pub use libc::c_char;